A client required help with a program that extracts the dominant color of a product image.
I was able to quickly implement this in Javascript; the algorithm below only samples the central square of a 3x3 grid on the image for a quick estimate of the t-shirt color in the image.
var image = new Image();
image.onload = function() {
try {
// get dominant color by sampling the central square of a 3x3 grid on image
var dominantColor = getDominantColor();
// output color
$("#output").html(dominantColor);
}
catch(e) {
$("#output").html(e);
}
};
image.src = "sample_image.jpg";
function getDominantColor() {
// Copy image to canvas
var canvas = $("<canvas/>")[0];
canvas.width = image.width;
canvas.height = image.height;
canvas.getContext("2d").drawImage(image, 0, 0);
// get pixels from the central square of a 3x3 grid
var imageData = canvas.getContext("2d").getImageData(canvas.width/3, canvas.height/3, canvas.width/3, canvas.height/3).data;
var colorOccurrences = {};
var dominantColor = "";
var dominantColorOccurrence = 0;
for(var i = 0; i < imageData.length; i += 4) {
var red = imageData[i];
var green = imageData[i+1];
var blue = imageData[i+2];
//var alpha = imageData[i+3]; // not required for this task
var color = RGBtoHEX({"red": red, "green": green, "blue": blue});
if(colorOccurrences[color] == undefined) {
colorOccurrences[color] = 1;
}
else {
colorOccurrences[color] ++;
if(colorOccurrences[color] > dominantColorOccurrence) {
dominantColorOccurrence = colorOccurrences[color];
dominantColor = color;
}
}
}
return dominantColor;
}
function RGBtoHEX(rgb) {
var hexChars = "0123456789ABCDEF";
return "#"
+ (hexChars[~~(rgb.red/16)] + hexChars[rgb.red%16])
+ (hexChars[~~(rgb.green/16)] + hexChars[rgb.green%16])
+ (hexChars[~~(rgb.blue/16)] + hexChars[rgb.blue%16]);
}
The image in question is this (preview below).
However, the results when this image is processed in the code above are varied across machines/browsers: #FF635E
is what I see on my machine, running Windows7 and using Firefox 32. My client running Mac gets a result of #FF474B
on Safari and #FF474C
on Firefox 33.
Though the results are close, why are they ideally not the exact same? Does getImageData
indeed vary depending on the local setup, or is the JPG data being interpreted differently on different machines?
Edit: This image isn't a one-off case. Such color variations were noticed across a range of the image that the client requested to process. My client and I obtained different results for the same set of images.