【问题标题】:The fastest way of rendering bmp file渲染bmp文件的最快方法
【发布时间】:2014-03-19 21:14:44
【问题描述】:

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

PS 中包含的解码时间在所有情况下都是相同的。

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

【问题讨论】:

  • 如果文件那么大并且您想完全加载它,我认为没有什么可做的。也许您可以尝试使用Zoomify 之类的方法来改变解决问题的方法
  • 黑白页。我不确定颜色数据,但如果它非常重要,可以检查 bmp 标头。
  • MarcoCI,也许我可以用低分辨率重建它?但我担心它会太慢。因为我们需要在客户端做所有事情。

标签: javascript canvas binary webgl blob


【解决方案1】:

我不确定你所说的 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

【讨论】:

    【解决方案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);
    

    祝你的项目好运!

    【讨论】:

    • 我不需要下载文件。它已经下载(在 Blob 中的客户端上渲染,问题是渲染速度有多快)。在您的示例中,您在画布上使用 drawImage 。我们发现有几个问题。 (糟糕的调整大小,我们需要等待加载 img 对象等)也许我们可以在 DOM 中附加 img 吗?为什么我们应该使用drawImage?它更快吗?没有在画布中渲染?我想补充一下,我们已经在 Blob 对象中有 BMP。我们不需要下载它,因为我们以某种特定的格式下载,并在 Blob 中的客户端机器上对其进行解码。
    • 但是你的回答还是很有帮助的!所以投票。
    • 到客户端的图像格式是DJVU块,我们在浏览器中通过客户端机器上的javascript将其解码为BMP。所以网络没有问题。我们尝试将 src 指定为 data:uri。以及您提出的许多其他方式。但是这种方法需要在base64中编码BMP,这需要时间。您需要加载图像对象。问题是可能存在一些更快地绘制图像的方法?例如在没有加载 img 对象的画布中?(当然会占用一些内存)
    猜你喜欢
    • 2017-03-06
    • 2021-12-29
    • 2014-05-21
    • 1970-01-01
    • 1970-01-01
    • 2013-11-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多