【问题标题】:Reading image.data from canvas-Element: Data is different for same image从 canvas-Element 读取 image.data:同一图像的数据不同
【发布时间】:2014-06-19 14:57:44
【问题描述】:

我对画布中的图像有疑问。

HTML1: 我尝试在画布(HTML1)中创建图像。创建图像(在本例中为一些随机像素)后,我将画布替换为图像(toDataURL())并使用右键单击和“另存为”浏览器功能保存图像。我将它保存为与 HTML2 文件相同的目录中的“Download.png”。 在我的 drawImage 函数结束时,我制作了一个 console.log(img.data);用于调试图像数据(对我的问题很重要!)。

HTML2: 我将图像 (Download.png) 从 HTML1 加载到我的画布中,并尝试再次获取图像数据 (ctx.getImageData(...))。现在,数据与 HTML1 中的数据不同,但它是相同的图像。 例如: 输出 HTML1:

[47, 42, 27, 49, 45, 54, 45, 57, 56, 48, 48, 32, 48, 48, 43, 48, 48, 43, 48, 48, 49, 49, 25, 42, 38, 11, 0, 47, 41, 29, 46, 106, 111, 98, 94, 115, 101, 41, 104, 81, 116, 97, 114, 121, 46, 105, 109, 117, 91, 108, 119, 45, 39, 39, 50, 46, 49, 44, 107, 105, 109, 43, 102, 115, 41, 29, 46, 106, 111, 98, 94, 115, 100, 44, 83, 105, 115, 112, 47, 87, 101, 96, 47, 104, 101, 104, 109, 101, 111, 43, 102, 115, 41, 29, 46, 106, 111, 98, 94, 115…]

输出 HTML2:

[211, 150, 67, 46, 5, 156, 196, 103, 250, 61, 235, 217, 131, 19, 71, 162, 160, 117, 115, 242, 190, 157, 33, 39, 0, 39, 59, 26, 226, 66, 45, 62, 55, 87, 47, 223, 216, 50, 213, 97, 227, 47, 214, 81, 163, 215, 176, 240, 25, 16, 151, 113, 131, 179, 158, 224, 147, 209, 200, 237, 239, 178, 136, 222, 80, 240, 169, 236, 123, 52, 143, 89, 8, 92, 66, 194, 64, 32, 69, 48, 38, 143, 53, 68, 213, 221, 99, 186, 172, 117, 193, 168, 0, 0, 0, 0, 79, 157, 255, 237…]

为什么?有人可以向我解释一下吗?为什么 image.data 不同?据我了解,它应该返回与 HTML1-example 中相同的 rgba-data。我该如何解决这种行为?我想要完全相同的数据。

提前谢谢你!

我创建了以下测试用例,希望每个人都能理解我的问题。

HTML1:

    <canvas id="canvas" height="100" width="100"></canvas>
    <script type="text/javascript">

        (function(){


            var canvas = document.getElementById('canvas'),
                ctx = canvas.getContext("2d");

                drawImage(ctx);
                replace_canvas_with_img();


        })();


        function drawImage(ctx) {
            var color = [],
                img = ctx.createImageData(canvas.width,canvas.height);

            for (var i=img.data.length;i--;) {

                //generate random color (rgba)
                for (var c = 4; c--;) {
                    color[c] = ''+Math.floor(Math.random() * (255 - 0 + 1));
                }

                //add random color to image.data;
                for (var ci = color.length; ci--;) {
                    img.data[i+ci] = color[ci];
                }

                color.length = 0;
            }
            ctx.putImageData(img, 0, 0);
            console.log(img.data);

        }               

        function replace_canvas_with_img() {
            document.write('<img src="' + canvas.toDataURL('image/png', 1) + '" />');
            canvas.parentNode.removeChild(canvas);

        }

    </script>

HTML2:

    <canvas id="canvas" height="100" width="100"></canvas>
    <script type="text/javascript">

        (function(){

            var myImg = new Image();
            myImg.src = 'Download.png';
            myImg.onload = function() {
                var canvas = document.getElementById('canvas'), 
                    ctx;

                canvas.width = myImg.width;
                canvas.height = myImg.height;

                ctx = canvas.getContext("2d");
                ctx.drawImage(this, 0,0);

                var imgData = ctx.getImageData(0,0,canvas.width, canvas.height);

                console.log(imgData.data);



            }   

        })();

    </script>

【问题讨论】:

标签: javascript html image canvas png


【解决方案1】:

我们问题中两个数组的巨大差异可能是用户错误。与下载的 png 相比,HTML1 可能已刷新。

由于 putPixelData 的有损特性,您会看到两个数组的细微差别。

见: This SO 问题和 thisHTML5 Canvas Spec

如果将pixel get和pixel data放在同一个HTML文件中,可以清楚地看到细微的差别。 IE。在您的第一个 console.log 语句之后将此行添加到 HTML1。

console.log(ctx.getImageData(0,0,canvas.width, canvas.height).data);

【讨论】:

  • 嗨,Charles,不,我在创建图像后没有刷新 HTML1。我将图像保存到磁盘并使用 HTML2 打开了一个新选项卡(包括从 HTML1 保存的图像)。但我认为你是对的 - 这似乎是 putPixelData 的有损性质。是否有任何解决方法,或者我是否必须遍历我的数组才能将所有像素一对一地放到我的画布上?
  • 如果你看到的变化真的那么大,那么就发生了可怕的错误。 get/put PixelData 不应导致可见的更改。您可以尝试其他方法,也许使用 drawImage 会起作用?也许您问错了问题,您要解决的需要无损图像编码/解码的更高级别的问题是什么?画布可能不是适合这项工作的工具。
  • 图片看起来一模一样。但是我必须读取 image.data 来验证它是同一个图像,如果 image.data 不同,我无法验证它。
猜你喜欢
  • 1970-01-01
  • 2014-10-24
  • 1970-01-01
  • 2016-06-12
  • 1970-01-01
  • 1970-01-01
  • 2015-01-28
  • 1970-01-01
相关资源
最近更新 更多