当前位置: 首页 > 知识库问答 >
问题:

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

颛孙霖
2023-03-14

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

我能够用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的客户端在Safari和Firefox 33上分别获得#FF474B#FF474C的结果。

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

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

共有1个答案

爱炯
2023-03-14

是的。这一事实被帆布指纹所利用:

同一个HTML5 Canvas元素可以在不同的网络浏览器上产生特殊的像素,这取决于执行它的系统。

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

 类似资料:
  • 本文向大家介绍javascript 判断是否是微信浏览器的方法,包括了javascript 判断是否是微信浏览器的方法的使用技巧和注意事项,需要的朋友参考一下 用js判断当前环境是否是是微信内置浏览器有两个方法: 1.判断useragent 2.判断是否支持微信内置浏览器才支持的一些方法,比如WeixinJSBridge 本次先介绍第一中方法,第二种方法等哪天再更新! 判断代码如下: 就是如此简单

  • 如何检查网页是否已被手机浏览器或电脑浏览器打开。我试过这个: 但它给出了这些类型的结果: 对于Fedora Firefox浏览器:Mozilla/5.0(X11;Linux i686;rv:13.0)Gecko/20100101 Firefox/13.0 从以上两个结果中,我无法区分网页是被手机还是电脑访问的。我该怎么做? 如果我能在Java做到这一点,那就太好了。

  • 本文向大家介绍是否有浏览器还支持HTML5的checkValidity()方法?,包括了是否有浏览器还支持HTML5的checkValidity()方法?的使用技巧和注意事项,需要的朋友参考一下 是的,在Google Chrome和Opera中也可以使用。这也很好- 示例

  • 问题内容: 为了澄清当我询问浏览器到浏览器的通信时,我的意思是在转发消息之间没有服务器。我想为游戏实现这样的功能。如果无法在websockets中使用p2p,是否有类似的选择?任何帮助表示赞赏。 问题答案: 否。浏览器只能启动WebSockets连接,不能接收它们。在W3C的浏览器API规范只定义了如何启动出站连接。 您可以创建一个既可以启动也可以接受WebSockets连接的应用程序,但是浏览器

  • 到现在为止,我们使用的canvas元素一直采用固定的500像素的宽度和高度。这个尺寸没有问题,但是如果我们想要将它填满整个浏览器窗口,又该如何做呢?对于普通的HTML元素,可以将width和height属性设置为100%,然后一切就都满足要求了。然而,canvas元素并不支持这种方法,它会忽略百分比,将100%解释为100像素,200%解释为200像素,以此类推。因此,我们需要使用另一种方法。 最

  • 本文向大家介绍JavaScript检测浏览器cookie是否已经启动的方法,包括了JavaScript检测浏览器cookie是否已经启动的方法的使用技巧和注意事项,需要的朋友参考一下 本文实例讲述了JavaScript检测浏览器cookie是否已经启动的方法。分享给大家供大家参考。具体分析如下: JavaScript检测浏览器cookie是否已经启动,代码稍显复杂,通过写入一个测试cookie判断