HTML5的canvas getImageData()执行失败。

10

当我使用getImageData()函数获取chrome中图像数据时,它会显示Uncaught IndexSizeError: Failed to execute 'getImageData' on 'CanvasRenderingContext2D': The source width is 0。

这是我的代码:

<!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>

它是如何发生的?如何修复?

2个回答

9
您正在附加一个onload回调函数来实际将图像绘制到画布上。但是,这只有在图像在DOM中加载并且必须从服务器获取时才会触发。您认为这些操作在尝试从画布提取图像数据之前就已经完成了吗?
这就是混合同步和异步代码时的问题,有许多技术可以解决它。但我敢打赌,在调试器中在绘制图像的行和尝试读取它的行设置断点后,后者会在前者之前触发。
要么您需要将处理过程放在onload处理程序中(不建议因为会产生耦合),要么使用像promise这样的东西来确保读取数据的代码在写入数据的代码之后运行。

3

如果您意外地将0传递给widthheight参数,也会出现该错误消息:

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

无论是由于打字错误还是变量错误,将0传递给第三个或第四个参数都会导致错误消息为“源宽度为0”或“源高度为0”。

因此,您应该直接引用画布的宽度/高度,而不是这样做:

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

或者添加一个条件,检查确保两个值都不是假值:

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

else
{
    alert('Invalid canvas width or height value!');
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接