画布getImageData方法是机器/浏览器依赖吗?

时间:2014-10-28 18:16:07

标签: javascript canvas colors getimagedata

客户需要帮助提取产品图像主色的程序。

我能够在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(预览如下)。

Sample product

但是,在上述代码中处理此图片时的结果因机器/浏览器而异: #FF635E 是我在计算机上看到的,运行Windows7并使用Firefox 32。运行Mac的客户端在Safari上获得 #FF474B ,在Firefox 33上获得 #FF474C 的结果。

虽然结果很接近,但为什么它们理想情况不完全相同? getImageData确实会因本地设置而异,或者是JPG数据在不同的机器上被不同地解释?

修改:此图片不是一次性案例。在客户要求处理的一系列图像中注意到这种颜色变化。我的客户和我为同一组图像获得了不同的结果。

1 个答案:

答案 0 :(得分:6)

是。这个事实被canvas fingerprinting

利用
  

相同的HTML5 Canvas元素可以   在不同的Web浏览器上生成特殊像素,具体取决于   执行它的系统。

     

出现这种情况有几个原因:图像格式级别 - 网络   浏览器使用不同的图像处理引擎,导出选项,   压缩级别,最终图像即使它们也可能有不同的哈希值   像素完美;在pixmap级别 - 操作系统使用   抗锯齿和子像素的不同算法和设置   渲染。我们不知道所有原因,但我们已经知道了   收集了一千多个独特的签名。