我正在使用drawImage method for slicing an image运行MDN教程。精简页面代码如下所示:
<html>
<head>
<script type="application/x-javascript">
function draw() {
var ctx = document.getElementById('canvas').getContext('2d');
ctx.drawImage(document.getElementById('frame'),0,0);
ctx.drawImage(document.getElementById('source'),33,71,104,124,21,20,87,104);
}
</script>
</head>
<body onload="draw();">
<canvas id="canvas" width="150" height="150"></canvas>
<img id="source" src="images/rhino.jpg" width="300" height="227" alt="">
<img id="frame" src="images/picture_frame.png" width="132" height="150" alt="">
</body>
</html>
从MDN网站运行完整版时,它按预期工作。当复制到我的本地机器并从“file:///”url(具有正确的图像相对路径)加载时,这将在drawImage ...'source'行上抛出INDEX_SIZE_ERR。
图片通过img标签按预期加载。
将document.getElementById('source')
分配给变量并将该变量传递给drawImage
表示该变量为非null且classWidth为300(通过简单的alert
),并仍然抛出错误。
ctx.drawImage(document.getElementById('frame'),0,0);
行确实正确地绘制到画布。
为什么我的本地计算机的行为与Web版本不同?安全限制? (新手在这里,如果答案很简单,请道歉。)
答案 0 :(得分:6)
您收到INDEX_SIZE_ERR
,因为您正在调用drawImage()
,其参数为负数或超出数据范围。在这种情况下,我们可以排除负值。
相反,您可能会看到错误,因为您要求提供源图像数据维度之外的信息。当您指定源和目标坐标和尺寸时(正如您在此处所做的那样), 允许传递超出目标尺寸范围的值(正面和负面)。你可能遇到麻烦的地方是源值。
在您的情况下,我认为正在发生的事情是您的源图像实际上不是300px by 227px
,尽管您在CSS中表示了什么。即使图像可能在浏览器中显示得很大,但是加载到DOM中的图像对象中存储的实际像素数也较小。因此,即使您对drawImage()
的调用具有为每个DOM元素指定的大小调整的有效参数,您也要求33 -> 137
维度中的像素x
和像素71 -> 195
在y
维度。这些范围中的一个(或两个)超出了源图像的尺寸。仔细检查源图像的实际大小。
至于为什么你在本地和网络执行之间遇到不同的行为,你可能会在请求图像时遇到问题。除了您通常无法在本地操作画布元素(除非您设置特殊开发环境或手动配置浏览器)之外,无论位置如何,图像仍然必须“下载”到您的浏览器。浏览器中的图像采集是异步完成的,所以考虑到现在的代码,当调用draw()
函数时,两个(或任一个)图像在内存中都可用时,无法保证。
相反,你应该做的是使用内置于图像元素中的onload
回调函数。在您的情况下,由于您有两个图像,您需要维护一个标志以确定何时加载两个图像。您可以尝试这样的事情:
<html>
<head>
<script type="application/x-javascript">
var images_loaded = 0;
function imageLoaded() {
++images_loaded;
if (images_loaded == 2) {
draw();
}
}
function draw() {
var ctx = document.getElementById('canvas').getContext('2d');
ctx.drawImage(document.getElementById('frame'),0,0);
ctx.drawImage(document.getElementById('source'),33,71,104,124,21,20,87,104);
}
</script>
</head>
<body>
<canvas id="canvas" width="150" height="150"></canvas>
<img id="source" onload="imageLoaded();" src="images/rhino.jpg" width="300" height="227" alt="">
<img id="frame" onload="imageLoaded();" src="images/picture_frame.png" width="132" height="150" alt="">
</body>
</html>
请注意,对于rhino的drawImage()
调用中的参数问题仍然在上面的示例中;我不知道你的rhino.jpg图像的尺寸是多少,所以我不能推荐修正。