是canvas的getImageData方法的机器/浏览器依赖吗? [英] Is canvas getImageData method machine/browser dependent?

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

问题描述

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



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

  var image = new Image(); 
image.onload = function(){
try {
//通过对图像上的3x3网格的中心方格进行采样来获得主色彩
var dominantColor = getDominantColor();

//输出颜色
$(#output)。html(dominantColor);
}
catch(e){
$(#output)。html(e);
}
};
image.src =sample_image.jpg;

function getDominantColor(){

//将图像复制到画布中
var canvas = $(< canvas />)[0]
canvas.width = image.width;
canvas.height = image.height;
canvas.getContext(2d)。drawImage(image,0,0);

//从3x3网格的中心方块获取像素
var imageData = canvas.getContext(2d)。getImageData(canvas.width / 3,canvas.height / canvas.width / 3,canvas.height / 3).data;

var colorOccurrences = {};
var dominantColor =;
var dominantColorOccurrence = 0;

for(var i = 0; i 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 [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]);
}

有问题的图片是可利用此事实:


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



这是由于以下几个原因:在图像格式级别 - web
浏览器使用不同的图像处理引擎,导出选项,
压缩级别,最终图像可能有不同的哈希值,即使他们
是像素完美的;在像素级 - 操作系统使用
不同的算法和设置反锯齿和子像素
渲染。我们不知道所有的原因,但我们已经
收集了超过一千个独特的签名。



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:

The same HTML5 Canvas element can produce exceptional pixels on a different web browsers, depending on the system on which it was executed.

This happens for several reasons: at the image format level — web browsers uses different image processing engines, export options, compression level, final images may got different hashes even if they are pixel-perfect; at the pixmap level — operating systems use different algorithms and settings for anti-aliasing and sub-pixel rendering. We don't know all the reasons, but we have already collected more than a thousand unique signatures.

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

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆