小試牛刀,實作了六款簡單常見HTML5 Canvas特效濾鏡,並且封裝成一個純JavaScript可呼叫的API檔案gloomyfishfilter.js。 支援的特效濾鏡分別為: 1.反色 2.灰色調 3.模糊 4.浮雕 5.雕刻 6 .鏡像濾鏡原理解釋: 1.反色:取得一個像素點RGB值r, g, b則新的RGB值為(255-r, 255 -g, 255-b) 2.灰色調:取得一個像素點RGB值r, g, b則新的RGB值為
newr = (r * 0.272) (g * 0.534) (b * 0.131); newg = (rg * 0.349); * 0.686) (b * 0.168); newb = (r * 0.393) (g * 0.769) (b * 0.189);
3.模糊:基於一個5*5的捲積核
4. 浮雕與雕刻:
基於目前像素的前一個像素RGB值與它的後一個像素的RGB值之差再加上128
5.鏡像:模擬了物體在鏡子中與之對應的效果。
雜項準備
1.如何取得Canvas 2d context物件
複製程式碼
程式碼 var canvas = document.getElementById("target"); canvas.width = source.clientWidth; canvas.height = source.clientHeight; if(!canvas.getContext) { console.log("Canvas not supported. Please install a HTML5compatible browser."); return; }
// get 2D context of canvas and draw image
Context> ("2d");
2.如何繪製一個DOM img對像到Canvas對像中 複製代碼
程式碼如下:
var source = document.getElementById("source");
tempContext.drawImage(source, 0, 0, canvas.width,canvas.height); 🎜>
程式碼 var canvas = document.getElementById("target"); varlen = canvas.width * canvas.height * 4; var canvasData = tempContext.getImageData(0, 0, canvas. , canvas.height); var binaryData = canvasData.data;
4.如何對DOM物件實作滑鼠Click事件綁定
程式碼如下:
function bindButtonEvent(element, type, handler) { if(element.add >element.addEventListener(type, handler,false); }else { element.attachEvent('on' type, handler);// for IE6,7,8 } }
5.如何呼叫實作的gfilter API完成濾鏡功能
複製程式碼
複製程式碼
程式碼如下
複製程式碼
複製程式碼
程式碼如下:
應用程序源代碼: CSS部分: 複製代碼
代碼如下:
反色 灰色調整 灰色調整按鈕> 模糊按鈕> 浮雕 雕刻 鏡像 ;
身體>
filter1.html中JavaScript原始碼:
複製程式碼 程式碼如下:
var tempContext = null; // 全域變數2d 上下文 window.onload = function() { var source = document.getElementById("source"); var canvas = document.getElementById("source"); var canvas = document .getElementById("target"); canvas.width = source.clientWidth; canvas.height = source.clientHeight; if (!canvas.getContext) { console. ("不支援Canvas。請安裝HTML5 相容瀏覽器。"); 返回; } // 取得畫布的2D 上下文並繪製圖像 tempContext = canvas.getContext( "2d"); tempContext.drawImage(source, 0, 0, canvas.width, canvas.height); // 初始化運算button"); var adButton = document.getElementById("調整按鈕"); var BlurButton = document.getElementById("blur-button"); var reButton = document.getElementBy("救濟按鈕"); var dkButton = document.getElementById("diaoke-button"); varmirrorButton = document.getElementById("mirror-button"); // 綁定滑鼠點擊事件bindttonButton (inButton, "click", invertColor); bindButtonEvent(adButton, "點擊", adjustmentColor); bindButtonEvent(blurButton, "點擊", BlurImage); bindButton ); bindButtonEvent(dkButton, "點擊", kediaoImage); bindButtonEvent(mirrorButton, "點選",mirrorImage); } 函數🎜>{ if(element.addEventListener) { element.addEventListener(type, handler, false); } else { element.attachEvent('on' type, handler); //適用於IE6,7,8 } } function invertColor() { var canvas = document.getElementById("target"); var len = canvas.width * canvas.height * 4; var canvasData = tempContext.getImageData(0, 0, canvas.width, canvas.height); var binaryData = canvasData.data; // 處理所有處理所有像素 gfilter.colorInvertProcess(binaryData, len); // 將畫布資料複製回畫布 tempContext.putImageData(canvasData, 0, 0); } var canvas = document.getElementById("target"); var len = canvas.width * canvas.height * 4; var canvasData = tempContext.getImageData(0, 0, canvas. width, canvas.height); var binaryData = canvasData.data; // 處理所有像素 gfilter.colorAdjustProcess(binaryData, len); /// 將畫布資料複製回畫布 tempContext.putImageData(canvasData, 0, 0); } 函數blurImage() { var canvas = 函數blurImage() { var canvas = document.getElementById("target"); >var len = canvas.width * canvas.height * 4; var canvasData = tempContext.getImageData(0, 0, canvas.width, canvas.height); // 處理所有像素 gfilter.blurProcess(tempContext, canvasData); // 將畫布資料複製回畫布 tempContext.putImageData(canvasData, 0, 0); } function { var canvas = document.getElementById("target"); var len = canvas.width * canvas.height * 4; var canvasData = tempContext.getImageData(0, 0, canvas. width, canvas.height); // 處理所有像素 gfilter.reliefProcess(tempContext, canvasData); // 將畫布資料複製回畫布 tempContext.put🎜>// 將畫布資料複製回畫布 tempContext.put🎜>// 將畫布資料複製回畫布 tempContext.putImageData(canvasImageData(canvasImageDataM. 0, 0); } function kediaoImage() { var canvas = document.getElementById("target"); var len = document.getElementById("target"); var len = canvas.width * canvas. height * 4; var canvasData = tempContext.getImageData(0, 0, canvas.width, canvas.height); // 處理所有像素 gfilter.diaokeProcess(vastempContext, canvasData); // 將畫布資料複製回畫布 tempContext.putImageData(canvasData, 0, 0); } functionmirrorImage() { g🎜>functionmirrorImage() { 🎜> getElementById("target"); var len = canvas.width * canvas.height * 4; var canvasData = tempContext.getImageData(0, 0, canvas.width, canvas.height); 🎜>// 處理所有像素 gfilter.mirrorProcess(tempContext, canvasData); // 將畫布資料複製回畫布 tempContext.putImageData(canvasData, 0, 0); tempContext.putImageData(canvasData, 0, 0); } >
過濾原始碼(gloomyfishfilter.js):
複製程式碼程式碼如下:複製碼
var gfilter = { type: "canvas", name: "filters", author: "zhigang", getInfo: function () { return this.author ' ' this.type ' ' this.name; }, /** * ピクセルのカラー値を反転、新しいピクセル = RGB(255-r, 255-g, 255 - b) * * @param binaryData - キャンバスの imagedata.data * @param l - データの長さ (画像データの幅 * 高さ) */ colorInvertProcess: function(binaryData, l) { for (var i = 0; i var r = binaryData[i]; var g = binaryData[i 1]; var b = binaryData[i 2]; binaryData[i] = 255-r; binaryData[i 1] = 255-g; binaryData[i 2] = 255-b; } }, /** * カラー値を調整して、より暗く灰色にします... * * @param binaryData * @param l */ colorAdjustProcess: function(binaryData, l) { for (var i = 0; i < l; i = 4) { var r = binaryData[i]; var g = binaryData[i 1]; var b = binaryData[i 2]; binaryData[i] = (r * 0.272) (g * 0.534) (b * 0.131); binaryData[i 1] = (r * 0.349) (g * 0.686) (b * 0.168); binaryData[i 2] = (r * 0.393) (g * 0.769) (b * 0.189); } }, /** * キャンバスのディープクローン画像データ * * @param context * @param src * @returns */ copyImageData: function(context, src) { var dst = context.createImageData(src.幅、ソース高さ); dst.data.set(src.data); dst を返します。 }, /** * コンボリューション - ケネラル サイズ 5*5 - ぼかし効果フィルター (ぼかし効果) * * @param context * @param CanvasData */ blurProcess: function(context, CanvasData) { console.log("キャンバス フィルター - ぼかし処理"); var tempCanvasData = this.copyImageData(context, CanvasData); var sumred = 0.0、sumgreen = 0.0、sumblue = 0.0; for ( var x = 0; x < tempCanvasData.width; x ) { for ( var y = 0; y < tempCanvasData.height; y ) { // ピクセルのインデックス配列 var idx = (x y * tempCanvasData.width) * 4; for(var subCol=-2; subColvar colOff = subCol x; if(colOff = tempCanvasData.width) { colOff = 0; } for(var subRow=-2; subRowvar rowOff = subRow y; if(rowOff = tempCanvasData.height) { rowOff = 0; } var idx2 = (colOff rowOff * tempCanvasData.width) * 4; var r = tempCanvasData.data[idx2 0]; var g = tempCanvasData.data[idx2 1]; var b = tempCanvasData.data[idx2 2]; 合計 = r; サムグリーン = g; sumblue = b; } } // 新しい RGB 値を計算します var nr = (sumred / 25.0); var ng = (sumgreen / 25.0); var nb = (sumblue / 25.0); // 次のピクセルポイントの前をクリアします sumred = 0.0; サムグリーン = 0.0; サムブルー = 0.0; // 新しいピクセル値を割り当てます canvasData.data[idx 0] = nr; // 赤のチャネル canvasData.data[idx 1] = ng; // グリーン チャネル canvasData.data[idx 2] = nb; // ブルーチャンネル canvasData.data[idx 3] = 255; // アルファチャンネル } } }, /** * ピクセル値後 - ピクセル値 128 前 * レリーフ効果 */ reliefProcess: function(context, CanvasData) { console.log( 「キャンバスフィルター - レリーフプロセス」); var tempCanvasData = this.copyImageData(context, CanvasData); for ( var x = 1; x { for ( var y = 1; y { // 配列内のピクセルのインデックス var idx = (x y * tempCanvasData.width) * 4; var bidx = ((x-1) y * tempCanvasData.width) * 4; var aidx = ((x 1) y * tempCanvasData.width) * 4; // 新しい RGB 値を計算します var nr = tempCanvasData.data[aidx 0] - tempCanvasData.data[bidx 0] 128; var ng = tempCanvasData.data[aidx 1] - tempCanvasData.data[bidx 1] 128; var nb = tempCanvasData.data[aidx 2] - tempCanvasData.data[bidx 2] 128; nr = (nr 255) ? 255 : nr); ng = (ng 255) ? 255 : ng); nb = (nb 255) ? 255 : nb); // 新しいピクセル値を割り当てます canvasData.data[idx 0] = nr; // 赤のチャネル canvasData.data[idx 1] = ng; // グリーン チャネル canvasData.data[idx 2] = nb; // ブルーチャンネル canvasData.data[idx 3] = 255; // アルファチャンネル } } }, /** * before pixel value - after pixel value 128 * 雕刻效果 * * @param canvasData */ diaokeProcess: function(context, canvasData) { console.log("Canvas Filter - 進程"); var tempCanvasData = this. copyImageData(context, canvasData); for ( var x = 1; x { for ( var y = 1; y { // 數組中像素的索引 var idx = (x y * tempCanvasData.width) * 4; var bidx = ((x-1) y * tempCanvasData.width) * 4; var aidx = ((x 1) y * tempCanvasData.width) * 4; //計算新的RGB值 var nr = tempCanvasData.data[bidx 0] - tempCanvasData.data[ aidx 0] 128; var ng = tempCanvasData.data[bidx 1] - tempCanvasData.data[aidx 1] 128; var nb = tempCanvasData.data[bidx 2] - tempCanvasData.data[aidx 2] 128 ; nr = (nr ng = (ng nb = (nb // 分配新的像素值 canvasData.data[idx 0] = nr; / / 紅色通道 canvasData.data[idx 1] = ng; // 綠色通道 canvasData.data[idx 2] = nb; // 藍色通道 canvasData.data[idx 3] = 255 ; // Alpha 頻道 } } }, /** * 鏡像反射 * * @param context * @param canvasData */ mirrorProcess : function(context, canvasData) { console.log ( “畫布過濾器-過程”); var tempCanvasData = this.copyImageData(context, canvasData); for ( var x = 0; x { for ( var y = 0; y { // 陣列中像素的索引 var idx = (x y * tempCanvasData.width) * 4 ; var midx = (((tempCanvasData.width -1) - x) y * tempCanvasData.width) * 4; // 分配新的像素值 canvasData.data[midx 0] = tempCanvasData .data[idx 0]; // 紅色頻道 canvasData.data[midx 1] = tempCanvasData.data[idx 1]; ; // 綠色頻道 canvasData.data[midx 2] = tempCanvasData.data[ idx 2]; ; // 藍色通道 canvasData.data[midx 3] = 255; // Alpha 通道 } } }, };