本文介绍了canvas getImageData 方法是否依赖于机器/浏览器?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

一位客户需要有关提取产品图像主色的程序的帮助.

我能够在 Javascript 中快速实现这一点;下面的算法仅对图像上 3x3 网格的中心正方形进行采样,以快速估计图像中的 T 恤颜色.

var image = new Image();image.onload = 函数(){尝试 {//通过对图像上 3x3 网格的中心正方形进行采样来获得主色vardominantColor = getDominantColor();//输出颜色$("#output").html(dominantColor);}抓住(e){$("#output").html(e);}};image.src = "sample_image.jpg";函数 getDominantColor() {//复制图片到画布var canvas = $("")[0];canvas.width = image.width;画布高度 = 图像高度;canvas.getContext("2d").drawImage(image, 0, 0);//从 3x3 网格的中心正方形获取像素var imageData = canvas.getContext("2d").getImageData(canvas.width/3, canvas.height/3, canvas.width/3, canvas.height/3).data;var colorOccurrences = {};vardominantColor = "";vardominantColorOccurrence = 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];//这个任务不需要var color = RGBtoHEX({"red": red, "green": green, "blue": blue});if(colorOccurrences[color] == undefined) {colorOccurrences[颜色] = 1;}别的 {colorOccurrences[颜色]++;if(colorOccurrences[color]>dominantColorOccurrence){主要颜色出现 = colorOccurrences[颜色];优势颜色 = 颜色;}}}返回主色;}函数 RGBtoHEX(rgb) {var hexChars = "0123456789ABCDEF";返回 "#"+ (hexChars[~~(rgb.red/16)] + hexChars[rgb.red%16])+ (hexChars[~~(rgb.green/16)] + hexChars[rgb.green%16])+ (hexChars[~~(rgb.blue/16)] + hexChars[rgb.blue%16]);}

有问题的图片是利用了这一事实:

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

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

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.

解决方案

Yes. This fact is exploited by canvas fingerprinting:

这篇关于canvas getImageData 方法是否依赖于机器/浏览器?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

07-29 21:30
查看更多