客户需要帮助提取产品图像主色的程序。
我能够在Javascript中快速实现这一点;下面的算法只对图像上3x3网格的中心方块进行采样,以便快速估算图像中的T恤颜色。
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]);
}
相关图片为this(预览如下)。
但是,在上述代码中处理此图片时的结果因机器/浏览器而异: #FF635E
是我在计算机上看到的,运行Windows7并使用Firefox 32。运行Mac的客户端在Safari上获得 #FF474B
,在Firefox 33上获得 #FF474C
的结果。
虽然结果很接近,但为什么它们理想情况不完全相同? getImageData
确实会因本地设置而异,或者是JPG数据在不同的机器上被不同地解释?
修改:此图片不是一次性案例。在客户要求处理的一系列图像中注意到这种颜色变化。我的客户和我为同一组图像获得了不同的结果。
答案 0 :(得分:6)
是。这个事实被canvas fingerprinting:
利用相同的HTML5 Canvas元素可以 在不同的Web浏览器上生成特殊像素,具体取决于 执行它的系统。
出现这种情况有几个原因:图像格式级别 - 网络 浏览器使用不同的图像处理引擎,导出选项, 压缩级别,最终图像即使它们也可能有不同的哈希值 像素完美;在pixmap级别 - 操作系统使用 抗锯齿和子像素的不同算法和设置 渲染。我们不知道所有原因,但我们已经知道了 收集了一千多个独特的签名。