2014-02-19 85 views
0

我們在客戶端有一個二進制文件。它來自書籍的掃描頁面,以某種方式壓縮到客戶端。我們有一個解碼器(在客戶端),它輸出一個包含BMP數據文件的TypedArray。我們需要儘可能快地渲染它。 BMP大小約爲3000000字節(解碼後,它是返回的typedArray的長度)。我們嘗試了很多解決方案,但在慢速電腦上卻無法使用。例如我們發現的最快方式:我們從TypedArray構建blob。創建此Blob的URL並將其指定爲圖像源上的src屬性。花費大約22000ms來渲染20頁。我們還嘗試使用src標籤中指定的數據:URL(34000ms)在base64中呈現它。我們試圖在畫布上呈現它。但是有一些問題,比如我們在畫布上使用了需要加載圖像對象的drawImage。可能是一些我們如何使用WebGL和硬件加速來渲染它?渲染BMP文件的最快方法

PS在所有情況下包括的解碼時間相同的時間。

PS我可以附上我們試過的代碼示例。

+0

如果文件很大並且想要完全加載它,我認爲不需要做太多的事情。也許你可以嘗試用[Zoomify](https://github.com/turban/Leaflet.Zoomify) – MarcoL

+0

黑白頁面來改變問題的解決方法。我不確定顏色數據,但可以檢查bmp標題,如果它非常重要。 –

+0

MarcoCI,也許我可以用低分辨率重建它?但我擔心它會太慢。因爲我們需要在客戶端做所有的事情。 –

回答

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

2

物理定律始終適用:

大圖像需要更長的時間來下載比小的圖像。

作爲一個解決方法,「老式」方法如何。

Intially顯示你的書頁的「有損」版本(小.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"; 

當大的圖像是滿載,與.bmp圖像更換.JPG圖像

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

祝您的項目順利!

+0

我不需要下載文件。它已經下載(在Blob中的客戶端呈現,問題是渲染速度有多快)。在你的例子中,你在畫布上使用drawImage。我們發現有幾個問題。 (不好的工作調整大小,我們需要等待加載img對象無論如何等)可能是我們可以在DOM中追加img?爲什麼我們應該使用drawImage?速度更快嗎?沒有在畫布上渲染?我想添加我們已經在Blob對象中有BMP。我們不需要下載它,因爲我們以某種特定格式下載,並在Blob中的客戶機上解碼它。 –

+0

但是你的回答無論如何都非常有幫助!所以投票。 –

+0

來到客戶端的圖片格式是DJVU塊,我們在瀏覽器中通過客戶端機器上的javascript通過BMP解碼。所以在網絡中沒有問題。我們嘗試將指定的src作爲數據:uri。還有很多其他的方式,比如你提出的。但是這種方法需要在base64中編碼BMP,這需要花費時間。您需要加載圖像對象。問題是可能存在一些方法來更快地繪製圖像?例如在沒有加載img對象的畫布中(當然這需要一些內存) –