8

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

我能够在 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]);
}

有问题的图像是这个(下面的预览)。

样品产品

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

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

编辑:此图像不是一次性案例。在客户要求处理的一系列图像中发现了这种颜色变化。我和我的客户对同一组图像获得了不同的结果。

4

1 回答 1

7

是的。画布指纹利用了这一事实:

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

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

于 2014-10-28T18:31:32.097 回答