バックグラウンド設定
他の一連の画像から画像を作成する Web アプリケーションがあります。私が選択した方法は、一連の画像を読み込んで HTML キャンバスに配置することです。次に、各キャンバスを jpeg としてサードパーティ API にエクスポートし、それを使用toDataURL
して Blob に変換します。私が直面している問題は、これらのキャンバスの多くがすべてデータを jpg としてエクスポートしていて、多くのリソースを消費していることです。各キャンバスが を呼び出そうとすると、アプリケーションの速度が低下し、応答しなくなりますtoDataURL
。
質問
特にキャンバスのサイズが大きい場合、キャンバスのtoDataUrl()
orを呼び出すと非常に遅くなることがわかりました。toBlob()
Web ワーカーのマルチスレッドの性質を利用したいと考えています。
まず、canvas オブジェクトを渡そうとしましたが、エラーがスローされました。オブジェクトが問題であることが判明し、文字列に変換されるか、複製できない場合に失敗するようです。いずれにせよ、コンテキストの画像データを渡すとうまくいくことがわかりました。Uint8ClampedArray
データは、キャンバス コンテキストの method から生の RGB 値の形式で渡されますgetImageData()
。
Main.js
var canvas = document.createElement('canvas');
var context = canvas.getContext('2d');
var worker = new Worker('myWorker.js');
worker.postMessage({
image: context.getImageData(0, 0, canvas.width, canvas.height)
});
myWorker.js
this.onmessage = function(e) {
// GOAL: turn e.data.image into an image blob or dataUrl and return it.
// e.g. this.postMessage(new Blob([e.data.image.data], {type: 'image/jpg'});
}
Uint8ClampedArray
RGB情報を保持するaをjpg/pngデータに変換する方法を知ることになると思います。
これが便利だと思う理由はgetImageData
、キャンバス コンテキストから既存のデータ構造をコピーするだけなので、toDataUrl
. 以下のコード ブロックに似たものを呼び出しながら、CPU プロファイルをキャプチャしました。
var image = context.getImageData(0, 0, canvas.width, canvas.height)
var dataUrl = canvas.toDataURL('image/jpeg');
そして得た:
そのため、プロセスの負荷を Web ワーカーにオフロードしたいと思います。別のプロセスで発生している限り、Web ワーカー内で時間がかかってもかまいません。
それについてのいくつかの追加の考え:
- 変換を行うために追加のライブラリを追加することは問題ありませんが、Web ワーカー ファイルへの依存関係として外部ライブラリを追加する方法を提供するためのボーナス ポイントです。現在、アプリケーションに browserify を使用しています。おそらく、Web ワーカー用に別のブラウザ化されたバンドルを作成しますか?
- 最後に(サードパーティのAPI用に)jpegが必要なので、pngに変換するのは、jpegへの変換のステップになるだけです。
encoderOptions
プロセスを高速化する方法として、 の 2 番目のオプションである を下げてtoDataURL
みましたが、あまり変化が見られませんでした。