上篇介紹了HT for Web採用HTML5 Canvas的getImageData和setImageData函數,經過顏色乘積實現的染色效果,本文將再次介紹另外一種更爲高效的實現方式,固然要實現的功能效果是徹底同樣的。此次咱們依然基於HTML5技術,但採用Canvas的globalCompositeOperation屬性進行各類blending效果:html
各類globalCompositeOperation效果可參考https://developer.mozilla.org/en-US/docs/Web/API/Canvas_API/Tutorial/Compositing 的說明,咱們採用「multiply」和「destination-atop」這兩種blending效果,經過如下三個步驟實現:chrome
一、先以染色顏色填充圖片大小的矩形區域canvas
二、採用「multiply」進行drawImage的繪製,達到如下效果瀏覽器
三、最後一步採用「destination-atop」的globalCompositeOperation方式,再次drawImage,此次繪製效果將會摳出圖片像素區域,剔除非圖片部分,最終達到咱們所要的染色效果圖片:框架
全部代碼以下函數
function createColorImage2(image, color) { var width = image.width; var height = image.height; var canvas = document.createElement('canvas'); var context = canvas.getContext( "2d" ); canvas.width = width; canvas.height = height; context.fillStyle = color; context.fillRect(0, 0, width, height); context.globalCompositeOperation = "multiply"; context.drawImage(image, 0, 0, width, height); context.globalCompositeOperation = "destination-atop"; context.drawImage(image, 0, 0, width, height); return canvas; };
至此咱們有兩種大相徑庭的繪製方式,二者的代碼量差很少,該選擇誰呢?讓咱們測試下兩種實現方式的性能:性能
time = new Date().getTime(); for(var i=0; i<100; i++){ createColorImage1(image, 'red'); } console.log(new Date().getTime() - time); time = new Date().getTime(); for(var i=0; i<100; i++){ createColorImage2(image, 'red'); } console.log(new Date().getTime() - time);
我在mac air的chrome瀏覽器下測試了以上代碼,createColorImage1須要1630毫秒,createColorImage2須要29毫秒,二者相差56倍,也就是說採用globalCompositeOperation雖然進行了兩次drawImage,但性能依然遠高於經過getImageData逐個設置像素值的方式。測試
形成這種巨大差距的根本緣由在於createColorImage1的方式徹底基於CPU運算,js本就單線程,且密集數值運算也不是js的強項,而採用globalCompositeOperation的渲染方式,瀏覽器底層徹底能夠採用GPU等硬件加速的方式達到更加的性能,所以兩鍾方式性能差別幾十倍也不足爲奇了,有興趣可參考微軟的幾篇關於瀏覽器Canvas硬件加速相關的文章:spa
http://msdn.microsoft.com/en-us/hh562071.aspx
以上兩種方式都是基於HTML5的Canvas的2D方式,其實更直接藉助GPU的應該是Canvas的WebGL技術,下篇咱們將介紹更好玩的基於WebGL的Shading Language的像素操做方式,固然使用Hightopo的HT for Web不須要關心這些底層技術細節,HT會自動選擇最合適的染色機制,由於有些終端瀏覽器不支持globalCompositeOperation的功能,有些不支持WebGL的硬件加速,所以自動選擇最合適的渲染機制也是須要底層框架足夠智能化的。