2017-05-06 8 views
2

私は現在、HTML5 Canvasの画像に簡単なフィルタ効果を適用しています。ここで定義された技術と同様に:CSS3フィルター効果がHTML5 Canvasと同等以上に効果的なのはなぜですか?

HTML5 Canvas image contrast そしてこのHTML5 Rocks! blog post

でただし、この特定のアプローチは、すべてのピクセルを反復処理し、再描画の前に修飾子を適用する必要があり。私の特定のユースケースでは、画像を再描画するのに150ms +(650px PNGで650px)が必要です。

CSS3's filter property(コントラストまたは明るさ)を使用して同じ効果を適用すると10ms未満です。

私の質問は次のとおりです。CSS3のフィルタプロパティはどのように機能しますか?それはなぜそれほど効果的ですか? Canvasで同様のパフォーマンスを達成する方法はありますか?

答えて

2

キャンバスはAPIを介して公開されています。 JavaScriptはランタイムであり、これらの日々が厳しく最適化されていても、JavaScriptによるピクセル単位のアクセスで2Dグリッドを操作する場合は、実行時からバッファまでずっとそのアクセスのペナルティを支払うことになりますキャンバスに現在格納されている画像が各ピクセルのになります。この問題は、JavaScriptでフィルタコードを表現しているという事実に結びついています。最適化されていても、ランタイムの性質上、取り出すことができない罰則がいくつかあります。

CSS3フィルタは、多かれ少なかれローカルに格納された画像にアクセスし、GPUのシェーダプログラムは、例えば、GPU上で直接実行されていることを意味し、バルクに同じ変換を行うことができるブラックボックスでありますGPUのメモリ、GPU benefiting from its SIMD-class instructionsは、に設計され、ピクセルの行列全体を処理します。また、ローカルメモリにアクセスするネイティブコードは、取得するほど速く、詳細になることはありません。

GPUの助けを借りずにCPU上で実行している場合でも、私たちはネイティブフィルタカーネルを、バイトコードなしでRAM内の画像を直接操作することを話しています。あなたは希望のフィルタを宣言し、ユーザエージェントはキャンバスイメージ上のフィルタプログラムを呼び出します。 CPUはまた、明らかに有意に役立つデータベクトルに作用するSIMD命令を有する。フィルタコードはあなたのものではなく、あなたは名前で参照するだけです。

キャンバスピクセルデータに直接使用できるもののような種類のブラックボックスフィルタをCSSで適用できれば、おそらくCSSと同じスピードになるでしょう。最も重要な障害JavaScriptコードで表現されたピクセル単位のアクセスを高速化することはできません。これはJavaScriptに関するだけではありません。これは約粒度のデータアクセスです。この場合、カーネルをバルクでデータに適用すると、より高いレベルでカーネルコードを直接書き込むよりも速くなります。簡単に言えば、私は以下の最後のポイントにいます。今

、JavaScriptインタープリタがそれはすべてあなたから、SIMDを利用し、おそらくGPU shadersネイティブコードにそれをすべてを変換することができているという意味であなたのピクセル単位のインザループの操作を理解することができれば自由にタイプされたJavaScriptフィルターコードを使用すると、パフォーマンスのギャップを埋めることができます。しかし、複雑さをJavaScriptコンパイラ/インタプリタに移すことになります。そのようなスケールで最適化する問題は、まだコンピュータサイエンスのの問題を完全に解決していません。多分人工知能と機械学習が助けになるだろう、私はそれについては推測しない。気にしないで、JIT-compilingあなたのJavaScriptを等価なコードに変換してください。それは今まで何度も受け継がれていたものです。フリー・タイプのJavaScriptコードを、既知の、人間がするだろう。その後、同じコードを実行時のものに置き換えて、同じ結果が得られますが、最適なパフォーマンスが得られると思った結果を得るためにコンパイラによって書き込まれます。実際に

、私はあなたがCanvas APIに深く見てみる場合は、キャンバスベースのJavaScriptナイーブピクセルごとのフィルタを最適化する、(私は明白な理由のために、MDN -authorativeソース考えることができると思います)。画像データは、CanvasRenderingContext2D.getImageData()メソッド呼び出しから取得できるUint8ClampedArrayタイプでアクセスできます。この配列型は、filter,forEachmapreduceなどの興味深い「バルク」関数を持っています。キャンバスAPIドキュメントを閲覧するときは、demoscene人の考え方を想定して「ハッカー」のようなビットを考える必要があります彼らがあなたに与えることができる点で利用可能な方法とデータ型。これを行うための報酬は相当なものになります。

これで十分でない場合は、というサブセットのAPIであるWebGLでキャンバスをレンダリングすることができます。通常、GPUでのみ実行されるように実装されています。シェーダーはWebGLの一部であることが保証されています。つまり、WebGLを使用したあらゆる種類の先進的で超高速のキャンバスフィルタープログラムに自由に乗車できます。

+0

私はこのためのコメントではないことを知っているが、...うわー。細部と説明に驚かされます。私はあなたの時間を大いに感謝します! –

+0

実際にはブラウジング中にあなたの質問を見ました。私はこれに興味があり、グラフィック処理の背景から来ていたのは純粋な愚かな運でしたが、答えを書くのはすべての種類の権利を感じました。私はあなたがそれが役に立つと思ってうれしいです。間違いなくそれ以上のことはありますが、私はすでにそれが始まりのためにテキストの壁でありすぎるのではないかと恐れていました。 APIをよく見てください。 https://developer.mozilla.org/en-US/docs/Web/API/Canvas_API(* semi * -authorative source、心に留めておいてください)。私は実際にそれを改善するために答えに後でもっと答えを加えたいかもしれません。 – amn

関連する問題