Javascript Canvas drawImage在本地运行(但不是从web运行)时抛出索引大小错误
我正在运行MDN教程,使用。精简的页面代码如下所示:Javascript Canvas drawImage在本地运行(但不是从web运行)时抛出索引大小错误,javascript,html,canvas,Javascript,Html,Canvas,我正在运行MDN教程,使用。精简的页面代码如下所示: <html> <head> <script type="application/x-javascript"> function draw() { var ctx = document.getElementById('canvas').getContext('2d'); ctx.drawImage(document.getElementByI
<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>
函数绘图(){
var ctx=document.getElementById('canvas').getContext('2d');
ctx.drawImage(document.getElementById('frame'),0,0);
ctx.drawImage(document.getElementById('source'),33,71104124,21,20,87104);
}
当从MDN网站运行完整版本时,它将按预期工作。当复制到我的本地计算机并从“file://”url(具有正确的图像相对路径)加载时,这会在drawImage…“source”行上抛出索引大小错误
图像通过img标签按预期加载
将document.getElementById('source')
分配给变量,并将该变量传递给drawImage
,表明该变量为非空且类宽为300(通过一个简单的警报
),并且仍然抛出错误
ctx.drawImage(document.getElementById('frame'),0,0)代码>线条是否正确绘制到画布
为什么我的本地计算机的行为与web版本不同?安全限制?(这里的新手,如果答案很简单,请道歉。)您收到的是索引大小错误
,因为您调用的drawImage()
参数要么是负数,要么超出数据范围。在这种情况下,我们可以排除负值
相反,您可能看到错误,因为您要求的信息超出了源图像数据的维度。指定源坐标和目标坐标及标注时(如此处所述),允许传递目标标注边界以外的值(正数和负数)。可能会遇到麻烦的是源值
在你的例子中,我认为发生的事情是,你的源图像实际上不是300px乘227px
,不管你在CSS中表示什么。即使图像可能在浏览器中显示得那么大,但加载到DOM中的图像对象中存储的实际像素数也会更小。因此,即使您对drawImage()
的调用在为每个DOM元素指定大小的情况下具有有效的参数,您仍然需要x
维度中的像素33->137
,以及y
维度中的像素71->195
。其中一个(或两个)范围超出了源图像的尺寸。仔细检查源图像的实际大小
至于为什么在本地和网络执行之间会出现不同的行为,在请求映像时可能会遇到问题。除了通常无法在本地操作画布元素(除非设置特殊的开发环境或手动配置浏览器)之外,图像仍然必须“下载”到浏览器中,而不管其位置如何。浏览器中的图像采集是异步完成的,因此,鉴于您现在拥有的代码,当调用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>
已加载的变量=0;
函数imageLoaded(){
++加载的图像;
如果(加载的图像=2){
draw();
}
}
函数绘图(){
var ctx=document.getElementById('canvas').getContext('2d');
ctx.drawImage(document.getElementById('frame'),0,0);
ctx.drawImage(document.getElementById('source'),33,71104124,21,20,87104);
}
请注意,调用rhino的drawImage()
中的参数问题仍然存在于上述示例中;我不知道rhino.jpg图像的尺寸,因此我不建议更正。您的服务器上和本地的图像是否相同?@c69:是的,相同,从MDN站点复制。图像必须通过HTTP加载到同一域中。不支持本地文件系统。如果在本地运行,则没有域。@Caspar Kleijne:Hrm。不过,颠倒“源”和“帧”线的顺序,“帧”线会在画布上渲染画框图像。我在努力理解。。。为什么它只适用于一个drawImage调用,而不适用于另一个调用?谢谢由于document.getElementById('source')为null或0乘0像素,因此猜测。问题确实出在图片大小上。负载发生得很好。非常感谢您的帮助,这对于学习加载模型和调试器的机制非常有用。@JoeZoller没问题!我很高兴我们能解决这个问题