2012-09-20 75 views
0

因此,我使用此功能從用戶硬盤驅動器讀取圖像,並將它們顯示爲縮略圖(如果它們具有可使用FileAPI的瀏覽器):使用FileAPI減少內存和CPU使用率從讀取圖像

// loop over them sequentially to prevent hogging memory 
function load(i) { 
    reader.onload = (function(file) { 
     return function(e) { 
      var loadNext = function(i) { 
       if (data[i + 1] !== undefined) { 
        setTimeout(function() { 
         load(i + 1); 
        }, 100); 
       } 
      }; 

      if (e.target.result.match(/^data\:image\/.*$/) === null) { 
       loadNext(i); 
       return; 
      } 

      // output file name 
      placeholders[i].custom.children.title.html(file.name); 

      // the server has returned an error, don't load the image 
      if (placeholders[i].custom.error === true) { 
       placeholders[i].custom.update({loaded: true}); 
       loadNext(i); 
       return; 
      } 

      // create new image 
      var $image = $('<img />') 
       .attr('alt', '') 
       .attr('src', e.target.result) 
       .attr('title', file.name); 

      // setup remove link 
      placeholders[i].custom.children.remove 
       .click(function(event) {event.preventDefault();}) 
       .attr('data-file-name', file.name); 

      // once finished loading 
      $image.load(function() { 
       if (placeholders[i].custom.error !== true) { 
        placeholders[i].addClass('success').attr('id', 'preview-' + file.name) 
        placeholders[i].custom.children.content.html($image); 
       } 
       placeholders[i].custom.update({loaded: true}); 

       loadNext(i); 
      }); 
      return; 
     } 
    })(data[i]); 

    reader.readAsDataURL(data[i]); 
} 
load(0); 

問題是,如果他們上傳一個特別大的文件或大量的文件,那麼CPU使用率(鉻)和內存使用率(在Firefox中)往往會激增。

前段時間我正在解決這個問題(我不得不停止這個項目並回到它),並且我設法通過確保文件(來自<input type="file" multiple="multiple" />元素)按順序加載來抵消一些問題。不幸的是,這仍然不夠,所以我開始着手將數據加載到塊中,並在讀取每個塊(slice和readAsArrayBuffer)時添加一個很短的延遲,從而解決了大多數情況下的問題。

如何從陣列緩衝區輸出數據到畫布?我得到了最後一次展示的東西,但它被炒得面目全非。

+1

爲什麼這是一個問題?如果不打算全部使用它,花費額外的100美元來獲得更多內存或提供更多性能的CPU的意義何在?爲什麼人們擁有資源,但是如果他們沒有可以保存的資源,就不會使用他們的目標。這不是說如果你使用50%的CPU,你明天可以使用200%。 –

+0

因爲我正在開發一個客戶端應用程序,並且FileReader會在瀏覽器處理此操作時讓瀏覽器停止半分鐘。 – rich97

+0

請把你的三個問題分成三個問題。 –

回答

0

http://jsfiddle.net/8A3tP/1/

以下是我終於實現了它。我使用window.btoa()將二進制數據(使用readAsBinaryString而不是readAsArrayBuffer)轉換爲base64字符串。從那裏我可以創建一個圖像對象與var image = document.createElement('img'); image.src = result;並使用它來填充Canvas2DContext.drawImage(圖像,0,0)的畫布;