現在、2 つの高解像度画像を html5 キャンバス要素に結合しています。
最初の画像は JPEG で、すべてのカラー データが含まれています。2 番目の画像はアルファ マスクの PNG ファイルです。
次に、2 つを組み合わせて 1 つの RGBA キャンバスを作成します。
アプリは、アルファ チャネルも維持する必要がある 2048x2048 解像度の画像を扱っています。したがって、この方法を単に PNG を使用するのと同じように使用することで、平均ファイルサイズを約 2 ~ 3 MB から 50 ~ 130 KB と 10 KB の png アルファ マスクに減らしました。
私が使用する方法は次のとおりです。
context.drawImage(alpha_mask_png, 0, 0, w, h);
context.globalCompositeOperation = 'source-in';
context.drawImage(main_image_jpeg, 0, 0, w, h);
残念ながら、この操作には約 100 ~ 120 ミリ秒かかります。And は、イメージがロードされるときに、イメージの各ペアに対して 1 回だけ実行されます。これは通常は問題にはなりませんが、この場合、アニメーションは別のメインの可視キャンバス (これらの高解像度画像はソース アートです) にレンダリングされており、非常に顕著な 100 ミリ秒のジャダー (ほとんどは Firefox で認識可能) に悩まされています。新しいソース アートがストリーミングされ、ロードされ、結合されるたびに。
私が探しているのは、これを減らす方法です。
これが私がこれまでに試したことです:
- Google chrome に WebP を実装し、JPEG と PNG のアルファ マスクを完全に組み合わせる必要がなくなりました。Chrome のみで完璧ですが、主に Firefox 向けのソリューションが必要です (IE 10/11 では操作がはるかに高速に実行されるようです)。
- 画像を webworker にロードして両方をデコードしてから、それらを結合しようとしました。すべて純粋な JavaScript で。これは機能しますが、遅すぎて使用できません。
- WebP ポリフィルも使用してみました。Weppyは非常に高速で、webworker で実行してもメイン ループには影響しません。ただし、アルファ透明度をサポートしていないため、この方法は非常に近いため、役に立ちません。libwebpjsは webworker 内で正常に動作しますが、JPEG/PNG の私の手動デコードと同様に、遅すぎます。
編集:さらに明確にするために。転送可能なオブジェクトを使用して Webworkers からデータを転送しようとしましたが、結果を blob に変換して、メイン スレッドによってロードできる objectURL を作成しようとしました。メイン スレッドの遅延はなくなりましたが、画像のデコードに時間がかかりすぎます。
これにより、WebGLが残ります。JPEG と PNG の両方を別々のテクスチャとしてロードし、それらをシェーダーと組み合わせる必要があることを認識している以外は、WebGL がどのように機能するかを文字通り理解していません。しかし、どこから始めればよいか本当にわかりませんでした。
次のリンクのコードでしばらく遊んでみました。
WebGL を使用して 2 つのキャンバスを 1 つにブレンドする
しかし、役に立たない。正直なところ、画像をテクスチャとしてロードするのに、実際には元の方法よりも時間がかかるのではないかと心配しています。
要約すると、高解像度画像の操作を高速化する方法を本当に探しています。(1920x1080 - 2048x2048) WebGL またはその他の方法を使用する場合。
どんな助けや提案も大歓迎です。