6

here で説明されているように、ローカル画像をサムネイルとして読み込もうとしています。私のコードは以下です。

これは、小さな画像では問題なく機能します。ただし、より大きな画像 (4 MB など) を読み込もうとすると、大きな遅延が発生します。これを最適化する方法はありますか?

ありがとう

HTML

<input type="file" id="files" name="files[]" multiple />
<output id="list"></output>

Javascript

<script>
function handleFileSelect(evt) {
var files = evt.target.files; // FileList object

// Loop through the FileList and render image files as thumbnails.
for (var i = 0, f; f = files[i]; i++) {

  // Only process image files.
  if (!f.type.match('image.*')) {
    continue;
  }

  var reader = new FileReader();

  // Closure to capture the file information.
  reader.onload = (function(theFile) {
    return function(e) {
      // Render thumbnail.
      var span = document.createElement('span');
      span.innerHTML = ['<img class="thumb" src="', e.target.result,
                        '" title="', escape(theFile.name), '"/>'].join('');
      document.getElementById('list').insertBefore(span, null);
    };
  })(f);

  // Read in the image file as a data URL.
  reader.readAsDataURL(f);
}
}

  document.getElementById('files').addEventListener('change', handleFileSelect, false);
</script>
4

1 に答える 1

17

巨大な BLOB で非ストリーミング データを操作するメイン UI スレッドで何かを実行すると、常に遅延が発生します。遅延は、データの読み取りではなく、ブラウザ UI での画像のデコードと表示に起因します。これには、CPU と GPU メモリに大きなピクセル配列をプッシュする同期 UI 操作が含まれるためです。これは<img>、実際の画像データ サイズ (幅 * 高さ) のブロックでメモリを割り当てて移動するためです。これは、大きな画像には非常に大量であり、画面に表示するためだけに GPU にプッシュする必要のない詳細なデータです (遅延の原因となります)。数ミリ秒)。

読み取り中に画像を表示可能なサイズに縮小することで、ユースケースを最適化できる可能性が最も高い

  • メイン イベント ループがファイルをチャンク単位で読み取り、チャンクを WebWorker バックグラウンド スレッドに投稿してデコードする、純粋な Javascript JPEG デコーダーを使用します。デコーダ ライブラリの例https://github.com/notmasteryet/jpgjs/blob/master/jpg.js

  • <canvas>WebWorker が結果のピクセルを段階的にポストバックする要素を割り当てます。このキャンバス要素は、実際の画像サイズと一致する必要はありません (以下を参照)。

  • また、純粋な Javascript http://www.grantgalitz.org/image_resize/で画像を読みながら、WebWorker で画像を縮小することもできます。最初に 1:1 ピクセル マッピングとして監視する

  • WebWorker とメイン スレッドは、コピー不要の Transferable オブジェクトを使用してデータをプッシュできます

ただし、ここで説明するソリューションはほぼ完璧ですが、これを実装するには高度な Javascript スキルが必要であり、ソリューションはレガシー互換ではありません (Microsoft を参照)。

于 2012-12-25T14:54:50.573 に答える