【发布时间】:2012-12-06 17:10:19
【问题描述】:
我正在尝试渲染存储在 javascript Uint8Array 中的 PNG 图像。我最初尝试的代码如下:
var imgByteStr = String.fromCharCode.apply(null, this.imgBytes);
var pageImg = new Image();
pageImg.onload = function(e) {
// Draw onto the canvas
canvasContext.drawImage(pageImg, 0, 0);
};
// Attempt to generate the Data URI from the binary
// 3rd-party library adds toBase64() as a string function
pageImg.src="data:image/png;base64,"+encodeURIComponent(imgByteStr.toBase64());
但是,我发现由于某种原因,onload 函数从未运行(我在 chrome 中设置了断点,但它根本没有命中)。我发现如果我将 src 设置为 URL 而不是 Data URI,它可以正常工作。但是,由于一些限制,我不能直接引用图像的 URL,即必须从 UInt8Array 加载。
此外,更复杂的是,这些图像的大小可能是兆字节。根据我的阅读,尝试将数据 URI 用于非常大的图像存在兼容性问题。因此,我非常犹豫要不要使用它们。
因此,问题是 如何在不使用数据 URI 或直接引用图像 URL 的情况下将此字节数组作为 PNG 呈现到画布上下文中?
我也尝试过使用类似下面的方法来直接使用putImageData 函数来操作图像数据。请记住,我不是 100% 了解此功能的工作原理
var imgdata = canvasContext.createImageData(this.baseHeight, this.baseWidth);
var imgdatalen = imgdata.data.length;
for(var i=0; i<imgdatalen; i++) {
imgdata.data[i] = _this.imgBytes[i];
}
canvasContext.putImageData(imgdata, 0, 0);
它来自一个博客,我已经关闭了它的标签,因此对没有给予适当信任的灵感表示歉意。
另外,当我慢慢地敲打这件事时,我在 Chrome SECURITY_ERR: DOM Exception 18 中遇到了一个错误。事实证明,一旦使用 drawImage 将图像加载到画布中,如果没有一些额外的解决方法,就无法检索它。关于这个话题的Chromium Blog post 特别有用
【问题讨论】:
-
你查看
putImageData()了吗? -
只是为了好奇:图像数据是如何进入数组的?
-
@David:我已经研究了一下,但我的理解是这是针对原始图像数据,而不是 PNG 编码的图像数据。我试试看
-
@raghaw:它是通过异步 HTTP GET 请求下载的。之所以不能在这里直接引用 URL,是因为下一步(一旦我得到这个工作)是加密 GET 请求的结果,然后在 JS 中解密。因此,从长远来看,图像 URL 根本不会返回图像,而是一个加密的二进制文件。这是一个很长的故事,但我一直坚持;)
-
我知道这可能超出您的控制范围,但重新实现浏览器对加密的现有支持似乎......令人沮丧。你不能只使用HTTPS吗? FWIW 我在浏览器中对图像数据做了一些工作,但我不确定如何将编码的 PNG 字节转换为 32 位 ARGB 数据。也许您可以使用 Blob,然后将其分配为 Image 的 src,然后将图像绘制到画布上。这仅适用于某些浏览器。这对你来说是个问题吗?