Reputation: 23
I'm trying to use ImageMagick to extract the dominant color from photos, and get the results in Hex codes and listed in percentages.
What I currently use is this website - http://www.coolphptools.com/color_extract#demo
If you visit it and scroll down a bit, you'll see that for that flower it's showing #f0a800 first at 0.229702%, then #606030 at 0.175060%, and so on and so forth.
I googled and tried many different imagemagick codes that I found online, but not only did I not get the solution, in everything I tried I never even saw for example "#f0a800" in the results. I don't know how Imagemagick is extracting completely different results than that website, but there you go.
Anyone knows how to do this with Imagemagick?
Upvotes: 1
Views: 2475
Reputation: 53089
Here is how to do it on ImageMagick 7, using -kmeans to reduce the number of colors, but work on the full size image. This will need Unix tools: sed, awk and sort. But there should be Windows equivalents for those tools. The kmeans color reduction may still change the colors somewhat. But your input has thousands of colors. So just taking the top 10 colors from the histogram is not sufficient way to get a representative sample of the colors. Also tools that read hex values are not all consistent.
I also note that the link you provided does color reduction and also modified the colors to adjust for brightness changes. So it is hard to know exactly what he did or to have exactly the same algorithms.
area=$(magick sample.jpg -format "%[fx:w*h]" info:)
magick sample.jpg -kmeans 10 -format "%c" histogram:info: | sed 's/://g' | awk -v area=$area '{print 100*$1/area, "%,", $3}' | sed 's/ *//g' | sort -nr -k1,1 -t ","
19.1803%,#ED9305
15.1357%,#5C5E35
13.4008%,#FBC904
10.4773%,#47471C
9.70675%,#CA6206
9.3305%,#A12116
8.53437%,#79724D
6.27543%,#25190E
5.44294%,#DE4936
2.51592%,#DEA579
Here is the full Unix syntax code that will make the swatches:
area=$(magick sample.jpg -format "%[fx:w*h]" info:)
data=$(magick sample.jpg -kmeans 10 -format "%c" histogram:info: | sed 's/://g' | awk -v area=$area '{print 100*$1/area, "%,", $3}' | sed 's/ *//g' | sort -nr -k1,1 -t ",")
echo "$data"
magick -size 1x1 xc: swatches.png
for item in $data; do
color=`echo $item | cut -d, -f2`
magick swatches.png \( -size 100x100 xc:"$color" \) +append swatches.png
done
magick swatches.png -gravity west -chop 1x swatches.png
19.1803%,#ED9305
15.1357%,#5C5E35
13.4008%,#FBC904
10.4773%,#47471C
9.70675%,#CA6206
9.3305%,#A12116
8.53437%,#79724D
6.27543%,#25190E
5.44294%,#DE4936
2.51592%,#DEA579
Perhaps this will give a more accurate representation of the colors.
Upvotes: 4
Reputation: 53089
I have a bash unix shell script for ImageMagick called dominantcolor that will do what you want.
Input:
dominantcolor -n 10 -p all -u percent -s save sample.jpg
dominant colors:
percent,hexcolor
19.64%,#57572C
14.96%,#D9660F
12.52%,#AD4321
12.32%,#EB9004
10.84%,#EDA608
10.32%,#6C6E49
9.72%,#372612
6.28%,#F9D302
2.44%,#C09651
0.96%,#BCA07C
Swatches:
The script reduces the image to size 50x50 pixels first to save processing time.
Upvotes: 1