Вопрос

I have a question about images in a canvas.

HTML1: I try to create an image in an canvas (HTML1). After I create the image (in this case some random pixels), I replace my canvas with an image (toDataURL()) and save the image using right-click and "save as"-browser function. I save it as "Download.png" in the same directory as HTML2-file. At the end of my drawImage-function, I make an console.log(img.data); for debugging the image-data (important for my question!).

HTML2: I load the image (Download.png) from HTML1 into my canvas and try to get the image-data again (ctx.getImageData(...)). Now, the data is different from the data in HTML1, but it is the same image. For example: Output 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…]

Output 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…]

Why? Can somebody explain this to me? Why is the image.data different? As far as I have understood it, it should return the same rgba-data as in HTML1-example. How can I fix this behaviour? I want to have exactly the same data.

Thank you in advance!

I have created following testcase and I hope everybody will understand my problem.

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>
Это было полезно?

Решение

The large differences in the two array's in our questions are probably user error. HTML1 was probably refreshed before you compared with the Downloaded png.

You will see small differences in the two array's because of the lossy nature of putPixelData.

See: This SO question and this or the HTML5 Canvas Spec

You can see the small differences clearly if you put the pixel get and get the pixel data in the same HTML file. I.e. add this line to HTML1 after your first console.log statement.

console.log(ctx.getImageData(0,0,canvas.width, canvas.height).data);
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top