问题
I have a blog with a lot of articles, I was wondering how to build a function that can detect the dominant color of each article image and for each article set the background with the dominant color.
(I am using Django +1.8 and Python 3.4.x)
I'm trying to build it from scratch, what are the steps?
What should the color detection function looks like?
any thoughts/suggestions?
回答1:
Yeah I just wanted a schema of how it would work on django
Let's assume a skeleton similar to below
class Article(Model):
background_color = CharField(max_length=6) # hex code of color
class AricleImage(Model):
article = ForeignKey(Article)
image = ImageField()
def get_dominant_color(self):
return _get_dominant_color(self.image.open())
# or pass self.image.file, depending on your storage backend
# We'll implement _get_dominant_color() below later
def set_article_background_color(self):
self.article.background_color = self.get_dominant_color()
Django provices a ImageField which inherits from FileField
, which provides a .open()
method, which is what we've used above to get a handle on the image file (which will be passed to our scipy/PIL code below)
...to build a function that can detect the dominant color of each article image and for each article set the background with the dominant color.
To run this on all articles we can do:
for article_image in ArticleImage.objects.all():
article_image.set_article_background_color()
Let's adapt the code from this answer and make a function out of it:
import struct
import Image
import scipy
import scipy.misc
import scipy.cluster
NUM_CLUSTERS = 5
def _get_dominant_color(image_file):
"""
Take a file object and return the colour in hex code
"""
im = image_file
im = im.resize((150, 150)) # optional, to reduce time
ar = scipy.misc.fromimage(im)
shape = ar.shape
ar = ar.reshape(scipy.product(shape[:2]), shape[2])
print 'finding clusters'
codes, dist = scipy.cluster.vq.kmeans(ar, NUM_CLUSTERS)
print 'cluster centres:\n', codes
vecs, dist = scipy.cluster.vq.vq(ar, codes) # assign codes
counts, bins = scipy.histogram(vecs, len(codes)) # count occurrences
index_max = scipy.argmax(counts) # find most frequent
peak = codes[index_max]
colour = ''.join(chr(c) for c in peak).encode('hex')
return colour
Set the article background in the template
And lastly but not least, when you render the article, just use {{article.background_color}}
e.g. if you want to override a generic style.css
you could define a <style></style>
block in the HTML
<style>
body {
background: #{{article.background_color}};
}
</style>
(Just an example, you can also make django generate a /css/style-custom.css
file to include after your main /css/style.css
)
来源:https://stackoverflow.com/questions/34958777/django-detect-dominant-color-of-an-image