Javascript:将存储为Uint8Array的PNG渲染到没有数据URI的Canvas元素上 [英] Javascript: Render PNG stored as Uint8Array onto Canvas element without Data URI

查看:2118
本文介绍了Javascript:将存储为Uint8Array的PNG渲染到没有数据URI的Canvas元素上的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I'm trying to render a PNG image that is stored in a javascript Uint8Array. The code that I originally tried was the following:

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函数从未运行(我设置了断点)铬,它根本不打)。我发现如果我将src设置为URL而不是Data URI,它可以正常工作。但是,由于一些限制,我不能直接引用图像的URL,即它必须从 UInt8Array 加载。

However, I found that for some reason the onload function was never running (I had breakpoints set up in chrome and it simply never hit). I found that if I set the src to a URL instead of Data URI, it worked correctly. However, due to some constraints, I cannot directly refer to the image's URL, i.e., it must be loaded from the UInt8Array.

另外,为了使事情略微复杂化,这些图像的大小可能是兆字节。根据我的阅读,尝试将数据URI用于非常大的图像存在兼容性问题。因此,我对使用它们非常犹豫。

Also, to complicate things slightly more, these images may be megabytes in size. From what I have read, there are compatibility issues with attempting to use Data URIs for very large images. Because of this, I am extremely hesitant to utilize them.

因此,问题是如何将此字节数组作为PNG渲染到画布上下文中不使用数据URI或直接引用图像URL?

我也尝试使用类似的东西以下使用 putImageData 函数直接操作图像数据。请记住,我并不是100%了解此功能的工作原理

I've also tried using something like the following to manipulate the image data directly using the putImageData function. Keep in mind that I don't 100% understand how this function works

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);

它是从我关闭后的标签的博客中解除的,所以对不给予的灵感表示道歉适当的信用。

It was lifted from a blog whose tab I have since closed, so apologies to the inspiration for not giving appropriate credit.

此外,在慢慢锤击这件事的同时,我在Chrome中遇到了错误 SECURITY_ERR:DOM异常18 。事实证明,只要使用drawImage将图像加载到画布中,就无法在没有其他解决方法的情况下检索图像。 Chromium博客文章这个主题特别有用

Also, while slowly hammering away at this thing, I ran into an error in Chrome SECURITY_ERR: DOM Exception 18. Turns out that, as soon as an image is loaded inot a canvas using drawImage, it cannot be retrieved without some additional workarounds. A Chromium Blog post on the topic was especially useful

推荐答案

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

If you have the PNG data in memory (which I think is what you're describing) then you can create an image from it. In HTML it would look like:

 <img src="data:image/png;base64,KSjs9JdldhAlisflAkshf==" />

在JavaScript中你也可以这样做:

In JavaScript you can do the same:

var image = document.createElement('img');
    image.src = 'data:image/png;base64,' + base64Data;

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

Note that you can change the MIME type if you don't have PNG data.

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

You could then draw the image onto your canvas using context.drawImage(image, 0, 0) or similar.

因此,难题的其余部分是编码 Uint8Array的内容到Base 64数据。

So the remaining part of the puzzle is to encode the contents of your Uint8Array into Base 64 data.

var array = new Uint8Array(),
    base64Data = btoa(String.fromCharCode.apply(null, array));

函数 btoa 不是标准的,所以有些浏览器可能不支持它。但是,似乎大多数都是。否则,您可能会发现我使用的一些代码很有帮助。

The function btoa isn't standard, so some browsers might not support it. However it seems that most do. Otherwise you might find some code I use helpful.

我自己没有测试过这个!

I haven't tested any of this myself!

这篇关于Javascript:将存储为Uint8Array的PNG渲染到没有数据URI的Canvas元素上的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆