1

我只是在学习如何使用 HTML5 画布元素。我已经成功地绘制了矩形、调用getImageData、操作像素,然后putImageData看到矩形改变颜色等。

现在我正在尝试将图像加载到我遇到障碍的画布中。在调用drawImage画布的上下文之后,fillRect只在没有绘制图像的区域绘制,就像它在图像后面绘制矩形一样,即使它被调用 after drawImage。此外,putImageData停止工作,即使在包含矩形的可见区域上,我的像素操作也不再发生。如果我用 注释掉该行drawImage,它会再次起作用。

我想要做的是像处理矩形一样操作图像中的像素。有什么理由不这样做吗?

绘制图像代码:

var img = new Image();
img.onload = function () {
     //comment out the following line, everything works, but no image on canvas
     //if it's left in, the image sits over the rectangles, and the pixel
     //manipulation does not occur
     context.drawImage(img, 0, 0, width / 2, height / 2);
}
img.src = path;

绘制矩形代码:

for (var i = 0; i < amount; i++)
{
    x = random(width - size);
    y = random(height - size);
    context.fillStyle = randomColor();
    context.fillRect(x, y, size, size);
}

操作像素代码:

var imgd = context.getImageData(0, 0, width, height);
var pix = imgd.data;

//loop through and do stuff

context.putImageData(imgd, 0, 0);
4

2 回答 2

2

您发布的代码看起来没有什么特别错误的。给我们完整的代码或考虑以下内容:

  1. 您是否在任何地方更改 globalCompositeOperation?
  2. 正在randomColor()制作太透明而无法看到的颜色?
  3. 有没有你没有提到的剪辑区域?
  4. 您是否将所有内容都绘制到正确的上下文中?
  5. 是否存在拼写错误导致执行停止并导致错误?
  6. 您的事件顺序可能是错误的。您可以加载图像,然后绘制矩形,然后完成加载图像,这样看起来就好像矩形是在图像后面绘制的,而这只是事物的自然顺序。
  7. putImageData 是否会导致安全错误(在 Firefox 中更容易看到),因为已将来自不同域的图像绘制到画布上?此错误可能会停止所有后续绘图代码的执行,因此会产生您所描述的效果。看看你是否违反了这些规则之一。专门从不同的来源将图像绘制到画布上,然后尝试使用 getImageData。

很可能是我列表中的最后一项或倒数第二项让您感到悲伤。

尝试将图像托管在您自己的服务器上,看看它是否会消失,或者查看 Firefox 中的 Web 控制台,看看它是否在抱怨安全错误。

或者只是在 Chrome/IE9 中打开 Web 控制台,看看在绘制图像时绘制代码是否真的被命中

于 2011-09-22T12:22:10.990 回答
0

好的,西蒙让我走上了正确的道路。看起来浏览器对来自本地文件系统的文件与来自 Web 服务器的文件的处理方式不同——具体来说,图像文件被标记为origin-clean = false. 当我getImageData在绘制图像后尝试调用上下文时,这导致了安全异常(NS_ERROR_DOM_SECURITY_ERR 1000)。

解决方案 1 是将文件托管在 Web 服务器上。

解决方案 2 有点小技巧,但对我来说没问题:

try {
    try { 
        var imgd = context.getImageData(0, 0, width, height); 
    } catch (e) { 
    netscape.security.PrivilegeManager.enablePrivilege("UniversalBrowserRead");
        var imgd = context.getImageData(0, 0, width, height);
    }
} catch (e) {throw new Error("unable to access image data: " + e)}

如果抛出安全异常,浏览器会提示用户允许覆盖。

于 2011-09-23T02:22:01.907 回答