首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >Javascript:将存储为Uint8Array的PNG渲染到没有数据URI的画布元素上

Javascript:将存储为Uint8Array的PNG渲染到没有数据URI的画布元素上
EN

Stack Overflow用户
提问于 2012-12-19 18:59:48
回答 2查看 23.8K关注 0票数 24

我正在尝试渲染存储在javascript Uint8Array中的PNG图像。我最初尝试的代码如下:

代码语言:javascript
复制
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而不是数据URI,它可以正常工作。然而,由于一些限制,我不能直接引用图像的URL,也就是说,它必须从UInt8Array加载。

此外,更复杂的是,这些图像的大小可能是兆字节。据我所知,对于非常大的图像,尝试使用数据URI存在兼容性问题。正因为如此,我非常犹豫是否要使用它们。

因此,问题是如何在不使用数据URL或直接引用图像URL的情况下将此字节数组作为PNG呈现到画布上下文中?

我还尝试使用类似下面的代码,通过putImageData函数直接操作图像数据。请记住,我不是100%理解这个函数是如何工作的

代码语言:javascript
复制
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特别有用

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2012-12-19 20:07:38

如果内存中有PNG数据(我认为这就是您所描述的),那么您可以从它创建一个图像。在HTML中,它将如下所示:

代码语言:javascript
复制
 <img src="data:image/png;base64,KSjs9JdldhAlisflAkshf==" />

在JavaScript中,您可以执行相同的操作:

代码语言:javascript
复制
var image = document.createElement('img');
    image.src = 'data:image/png;base64,' + base64Data;

请注意,如果没有PNG数据,则可以更改MIME类型。

然后,您可以使用context.drawImage(image, 0, 0)或类似工具将image绘制到画布上。

因此,剩下的部分就是将Uint8Array的内容编码成base64数据。

代码语言:javascript
复制
var array = new Uint8Array(),
    base64Data = btoa(String.fromCharCode.apply(null, array));

函数btoa不是标准的,所以一些浏览器可能不支持它。然而,似乎most do。否则,您可能会发现some code I use很有帮助。

我自己还没有测试过这些!

票数 24
EN

Stack Overflow用户

发布于 2012-12-20 03:09:09

如果您已经有了UInt8Array,则应该考虑使用BlobcreateObjectURLcreateObjectURL分配了一个特殊的URL,允许浏览器访问内部创建的二进制数据blob,就像它是从外部加载的文件一样。

Where it is supportedcreateObjectURL是巨型数据URI的优秀替代方案。您可能仍然需要在Opera、IE<10以及除最新版本的移动浏览器之外的所有移动浏览器中使用数据URI。

代码语言:javascript
复制
var myArray; //= your data in a UInt8Array
var blob = new Blob([myArray], {'type': 'image/png'});
var url = URL.createObjectURL(blob); //possibly `webkitURL` or another vendor prefix for old browsers.
票数 31
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/13950865

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档