最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - HTML5 canvas getImageData() failed to execute - Stack Overflow

programmeradmin1浏览0评论

When I use the getImageData() function to get the data of a image with chrome, it says that Uncaught IndexSizeError: Failed to execute 'getImageData' on 'CanvasRenderingContext2D': The source width is 0. Here is my code:

<!DOCTYPE html>
<html>
<head>
    <title>canvastest</title>
</head>
<body>
<img src="flower.jpg" hidden />
<canvas id="drawing" width="600" height="532">a drawing of something</canvas>
<script type="text/javascript" >
    var drawing = document.getElementById("drawing");
    if (drawing.getContext){
        var context = drawing.getContext("2d"),
            image = document.images[0],
            imageData,data,
            i,len,average,
            red,blue,green,alpha;

        image.onload = function(){
            context.drawImage(image,0,0);
        };

        imageData = context.getImageData(0,0,image.width,image.height);
        data = imageData.data;

        for (i=0,len=data.length;i<len;i+=4){
            red = data[i];
            green = data[i+1];
            blue = data[i+2];
            alpha = data[i+3];

            average = Math.floor((red + green + blue) / 3);

            data[i] = average;
            data[i+1] = average;
            data[i+2] = average;
        }

        imageData.data = data;
        context.putImageData(imageData,0,0);
    }
</script>
</body>
</html>

How could it happended? And how to fix it?

When I use the getImageData() function to get the data of a image with chrome, it says that Uncaught IndexSizeError: Failed to execute 'getImageData' on 'CanvasRenderingContext2D': The source width is 0. Here is my code:

<!DOCTYPE html>
<html>
<head>
    <title>canvastest</title>
</head>
<body>
<img src="flower.jpg" hidden />
<canvas id="drawing" width="600" height="532">a drawing of something</canvas>
<script type="text/javascript" >
    var drawing = document.getElementById("drawing");
    if (drawing.getContext){
        var context = drawing.getContext("2d"),
            image = document.images[0],
            imageData,data,
            i,len,average,
            red,blue,green,alpha;

        image.onload = function(){
            context.drawImage(image,0,0);
        };

        imageData = context.getImageData(0,0,image.width,image.height);
        data = imageData.data;

        for (i=0,len=data.length;i<len;i+=4){
            red = data[i];
            green = data[i+1];
            blue = data[i+2];
            alpha = data[i+3];

            average = Math.floor((red + green + blue) / 3);

            data[i] = average;
            data[i+1] = average;
            data[i+2] = average;
        }

        imageData.data = data;
        context.putImageData(imageData,0,0);
    }
</script>
</body>
</html>

How could it happended? And how to fix it?

Share Improve this question edited Oct 25, 2022 at 11:55 Pikamander2 8,2994 gold badges54 silver badges73 bronze badges asked Oct 22, 2015 at 12:53 chensunnchensunn 1751 gold badge2 silver badges8 bronze badges
Add a comment  | 

2 Answers 2

Reset to default 12

You are attaching an onload callback to actually draw the image to the canvas. But that only fires once the image is loaded in the DOM and it has to be fetched from the server. What makes you think any of that happens before you try to pull the image data from the canvas?

That's the problem when mixing synchronous and asynchronous code, and there are numerous techniques for getting around it. But I'd bet money if you set a break point in the debugger at the line the draws the image and the line that tries to read it that the latter will trigger before the former.

You either need to put the processing in your onload handler (not recommended because of the coupling) or use something like a promise to make sure the code that reads the data runs after the code that writes it.

That error message will also occur if you accidentally pass 0 to the width or height parameter:

context.getImageData(0, 0, 0, 0); //Throws an IndexSizeError

Regardless of whether it was due to a typo or a bad variable, passing 0 to the third or fourth parameter will always result in an error message of "The source width is 0." or "The source height is 0."

So instead of doing that, you should either reference the canvas's width/height directly:

context.getImageData(0, 0, context.canvas.clientWidth, context.canvas.clientHeight);

Or add a condition that checks to make sure that neither value is falsy:

if (my_width && my_height)
{
    context.getImageData(0, 0, my_width, my_height);
}

else
{
    alert('Invalid canvas width or height value!');
}
发布评论

评论列表(0)

  1. 暂无评论