渲染bmp文件的最快方法

时间:2014-02-19 13:39:59

标签: javascript canvas binary webgl blob

我们在客户端上有一个二进制文件。这是来自书籍的scaned页面,以某种方式压缩到客户端。我们有一个解码器(在客户端上),它输出一个包含BMP数据文件的TypedArray。我们需要尽快呈现它。 BMP大小约为3000000字节(解码后,返回的typedArray的长度)。我们尝试了很多解决方案但是在慢速PC上它没有用。例如我们发现的最快方式:我们从TypedArray构建blob。创建此blob的URL并将其指定为图像源上的src属性。渲染20页需要大约22000ms。我们还尝试使用数据在base64中呈现它:在src标记中指定的URL也是(34000ms)。我们试图在画布上渲染它。但是有一些问题,例如我们在画布上使用drawImage需要加载图像对象。可能是我们如何使用WebGL和硬件加速来渲染它?

PS在包含解码时间的时间内,在所有情况下均相同。

PS我可以附加我们尝试的代码示例。

2 个答案:

答案 0 :(得分:2)

物理定律总是适用:

  

大图像下载的时间比小图片要长。

作为一种解决方法,如何采用“老式”方法。

最初显示您图书页面的“有损”版本(可能是一个小.jpg)。

var imgJPG=new Image();
imgJPG.onload=start;
imgJPG.src="yourBookPage.JPG";

function start(){
    context.drawImage(imgJPG,0,0);
}

同时开始异步下载您的大型.bmp

var imgPNG=new Image();
imgPNG.onload=start;
imgPNG.src="yourBookPage.bmp";

当大图像完全加载时,将.jpg图像替换为.bmp图像

function start(){
    context.clearRect(0,0,canvas.width,canvas.height);
    context.drawImage(imgPNG,0,0);
}

如果用户在加载.bmp之前添加绘图,则可以让它们直接在.jpg画布顶部的单独画布上绘制。然后,当加载.bmp时,您可以将新加载的.bmp

顶部的现有图形组合在一起
context.clearRect(0,0,canvas.width,canvas.height);

// draw the .png in the background

context.drawImage(imgPNG,0,0);

// add any user drawings on top

context.drawImage(theTempDrawingCanvasWithManyUserDrawings,0,0);

祝你的项目好运!

答案 1 :(得分:2)

我不确定BMP文件的含义,直到你的意思是Microsoft BMP format

我不知道该格式的所有细节,但是如果您手动将其解码为JavaScript中的像素,则可以通过将其上传到WebGL中的纹理直接显示解码数据,然后使用纹理渲染四边形

网上有关于如何在WebGL中渲染纹理四边形的示例。 Here's one

您可以使用

将数据上传到纹理
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 
              widthOfImageInPixels, heightOfImagePixels, 0
              gl.RGBA, gl.UNSIGNED_BYTE, someUint8ArrayWithWidthByHeightPixels);

请注意,如果您的像素不是RGB或RGBA,就像说它们是YUV或something you can create a shader to display them directly而不是将它们在JavaScript中转换为RGB / RGBA