2017-05-06 77 views
2

我目前正在爲HTML5 Canvas上的圖像應用簡單的濾鏡效果。到這裏定義的技術類似:爲什麼CSS3濾鏡效果比HTML5 Canvas等效物更高效?

HTML5 Canvas image contrast 而在這HTML5 Rocks! blog post

然而,這種特殊的方法需要在迭代的每個像素,並重繪前進行修改。對於我的特殊用例,這需要150ms +重新繪製我的圖像(650px×650px PNG)

使用CSS3's filter property(對比度或亮度)應用相同的效果需要少於10ms。

我的問題是:CSS3的過濾器屬性如何「引擎蓋下」工作?爲什麼它性能更高?有沒有在Canvas中實現類似性能的方法?

回答

2

Canvas通過API公開。 JavaScript是一種運行時,儘管今天嚴格優化,但如果您要通過JavaScript逐像素訪問來操作2D網格,您將支付從運行時一直到緩衝區的所有訪問的代價包含當前與畫布一起存儲的圖像,每個像素爲。這個問題必然伴隨着你用JavaScript來表達過濾器代碼,即使經過優化,運行時的本質決定了一些無法取出的懲罰。

甲CSS3濾波器是一個黑盒子,可以做相同的變換散裝,這意味着一個GPU的着色器程序,舉例來說,是直接在GPU運行,訪問存儲在所述更多或更少的局部圖像GPU的內存以及設計爲的GPU benefiting from its SIMD-class instructions來設計來處理像素的整個矩陣。此外,本地代碼訪問本地內存 - 幾乎儘可能快地得到,而不會涉及到細節。

即使在CPU上運行,在沒有任何GPU協助的情況下,我們也會直接操縱內存中的圖像,而不需要任何字節碼,更重要的是不考慮JavaScript。你聲明你想要的過濾器,用戶代理調用畫布圖像上的過濾器程序,就是這樣。 CPU也有SIMD指令來處理數據向量,這顯然有很大幫助。過濾器代碼甚至不是你的,你只能通過名稱引用它。現在,如果您可以將某種黑箱過濾器應用於CSS中的其中一種,直接將畫布像素數據直接應用,則您可能會達到與CSS相同的速度 - 因爲最重要的障礙以加快速度 - 用JavaScript代碼表示逐像素訪問 - 已被淘汰。所以這不僅僅是關於JavaScript,這大概是的粒度的數據訪問。在這種情況下,將內核應用於批量數據將始終比自己在更高級別上編寫內核代碼要快。簡而言之,這將我帶到了下面的最後一點。現在

,如果JavaScript解釋器可以瞭解您的逐像素IN-A-循環在這個意義上,它可以把它全部轉換成利用SIMD,甚至GPU shaders,所有從本機代碼操作自由輸入的JavaScript過濾器代碼,可以彌合性能差距。但是,你會被感動的複雜性成JavaScript編譯器/解釋器,以及此類規模優化的問題不是計算機科學徹底解決尚未問題。也許人工智能和機器學習會有所幫助,我不會在這方面進行推測。你要知道,我不是說JIT-compiling你的JavaScript以相當於原生代碼,它多年來一直是常態了,我說的是承認自由類型的JavaScript代碼爲類似的東西已知或者甚至任意圖像內核,就像一個人會。然後用一個運行時對應代碼替換所述代碼,該代碼給出相同的結果,但由編譯器編寫,以產生它認爲會產生最佳性能的結果。

在實踐中,我認爲你可以優化基於畫布的JavaScript天真的逐像素過濾器,如果你需要更深入地瞭解了Canvas API(我認爲MDN一個 -authorative來源,出於顯而易見的原因)。該圖像數據可以通過一個Uint8ClampedArray類型,其可以從CanvasRenderingContext2D.getImageData()方法調用獲得訪問。這種陣列類型有一些有趣的「批量」功能,如filter,forEach,map,reduce等。在瀏覽Canvas API文檔時,您需要考慮有點像「黑客」,以承擔demoscene人的心態 - 看着可用的方法和數據類型。這樣做的回報可能很大。

如果這還不夠,可以使用WebGL來渲染畫布,該API是OpenGL的子集,通常被實現爲專門在GPU上運行。着色器保證是WebGL的一部分,這意味着您可以獲得各種先進和超快速的WebGL濾鏡程序的免費票據,這些程序可以自己編寫,但通常在GPU上執行。

+0

我知道意見並非針對這一點,但...哇。驚訝於細節和解釋。我非常感謝你的時間! –

+0

其實,我看到你的問題,而只是隨便看看,這是純粹的好運氣,我在這一個興趣和一些背景與圖形處理的到來,感覺​​各種權利寫一個答案。我很高興你覺得它有用。這絕對是更多的東西,但我已經擔心這將是一個開始的文本牆太多。仔細看看API,f.e.請訪問https://developer.mozilla.org/en-US/docs/Web/API/Canvas_API(* semi * -authorative source,請記住,請牢記這一點)。我可能實際上想在稍後添加更多答案以改進它。 – amn