Canvas六种特效滤镜

 

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 = (r * 0.349) + (g * 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

tempContext = canvas.getContext("2d");

 

2.        如何绘制一个DOM img对象到Canvas对象中

var source = document.getElementById("source");

tempContext.drawImage(source, 0, 0, canvas.width,canvas.height);

3.        如何从Canvas对象中获取像素数据

var canvas = document.getElementById("target");

varlen = canvas.width * canvas.height * 4;

var canvasData = tempContext.getImageData(0, 0, canvas.width, canvas.height);

var binaryData = canvasData.data;

4.        如何对DOM对象实现鼠标Click事件绑定

function bindButtonEvent(element, type, handler) 

if(element.addEventListener){ 

       element.addEventListener(type, handler,false); 

    }else { 

       element.attachEvent('on'+type, handler);// for IE6,7,8

    } 

}

5.        如何调用实现的gfilter API完成滤镜功能

<scriptsrc="gloomyfishfilter.js"></script> //导入API文件

gfilter.colorInvertProcess(binaryData, len); //调用 API

 

6.        浏览器支持:IE, FF, Chrome上测试通过,其中IE上支持通过以下标签实现:

<meta http-equiv="X-UA-Compatible"content="chrome=IE8"

效果演示:

应用程序源代码:

CSS部分:

 

[css] view plain copy
 
  1. #svgContainer {  
  2.     width:800px;  
  3.     height:600px;  
  4.     background-color:#EEEEEE;  
  5. }  
  6.            
  7. #sourceDiv { float: left; border: 2px solid blue}   
  8. #targetDiv { float: right;border: 2px solid red}   
filter1.html中HTML源代码:

 

 

[html] view plain copy
 
  1. <!DOCTYPE html>  
  2. <html>  
  3. <head>  
  4. <meta http-equiv="X-UA-Compatible" content="chrome=IE8">  
  5. <meta http-equiv="Content-type" content="text/html;charset=UTF-8">  
  6. <title>Canvas Filter Demo</title>  
  7. <link href="default.css" rel="stylesheet" />  
  8. <script src="gloomyfishfilter.js"></scrip>  
  9. </head>  
  10. <body>  
  11.     <h1>HTML Canvas Image Process - By Gloomy Fish</h1>  
  12.     <div id="svgContainer">  
  13.         <div id="sourceDiv">  
  14.             <img id="source" src="../test.png" />  
  15.         </div>  
  16.         <div id="targetDiv">  
  17.             <canvas id="target"></canvas>  
  18.         </div>  
  19.     </div>  
  20.     <div id="btn-group">  
  21.         <button type="button" id="invert-button">反色</button>  
  22.         <button type="button" id="adjust-button">灰色调</button>  
  23.         <button type="button" id="blur-button">模糊</button>  
  24.         <button type="button" id="relief-button">浮雕</button>  
  25.         <button type="button" id="diaoke-button">雕刻</button>  
  26.         <button type="button" id="mirror-button">镜像</button>  
  27.     </div>  
  28. </body>  
  29. </html>  

 

filter1.html中JavaScript源代码:

 

[javascript] view plain copy
 
  1. var tempContext = null; // global variable 2d context  
  2. window.onload = function() {  
  3.     var source = document.getElementById("source");  
  4.     var canvas = document.getElementById("target");  
  5.     canvas.width = source.clientWidth;  
  6.     canvas.height = source.clientHeight;  
  7.       
  8.     if (!canvas.getContext) {  
  9.         console.log("Canvas not supported. Please install a HTML5 compatible browser.");  
  10.         return;  
  11.     }  
  12.       
  13.     // get 2D context of canvas and draw image  
  14.     tempContext = canvas.getContext("2d");  
  15.     tempContext.drawImage(source, 0, 0, canvas.width, canvas.height);  
  16.   
  17.        // initialization actions  
  18.        var inButton = document.getElementById("invert-button");  
  19.        var adButton = document.getElementById("adjust-button");  
  20.        var blurButton = document.getElementById("blur-button");  
  21.        var reButton = document.getElementById("relief-button");  
  22.        var dkButton = document.getElementById("diaoke-button");  
  23.        var mirrorButton = document.getElementById("mirror-button");  
  24.   
  25.        // bind mouse click event  
  26.        bindButtonEvent(inButton, "click", invertColor);  
  27.        bindButtonEvent(adButton, "click", adjustColor);  
  28.        bindButtonEvent(blurButton, "click", blurImage);  
  29.        bindButtonEvent(reButton, "click", fudiaoImage);  
  30.        bindButtonEvent(dkButton, "click", kediaoImage);  
  31.        bindButtonEvent(mirrorButton, "click", mirrorImage);  
  32. }  
  33.   
  34. function bindButtonEvent(element, type, handler)    
  35. {    
  36.     if(element.addEventListener) {    
  37.        element.addEventListener(type, handler, false);    
  38.     } else {    
  39.        element.attachEvent('on'+type, handler); // for IE6,7,8  
  40.     }    
  41. }    
  42.   
  43. function invertColor() {  
  44.     var canvas = document.getElementById("target");  
  45.     var len = canvas.width * canvas.height * 4;  
  46.     var canvasData = tempContext.getImageData(0, 0, canvas.width, canvas.height);  
  47.     var binaryData = canvasData.data;  
  48.          
  49.        // Processing all the pixels  
  50.        gfilter.colorInvertProcess(binaryData, len);  
  51.   
  52.        // Copying back canvas data to canvas  
  53.        tempContext.putImageData(canvasData, 0, 0);  
  54. }  
  55.   
  56. function adjustColor() {  
  57.     var canvas = document.getElementById("target");  
  58.     var len = canvas.width * canvas.height * 4;  
  59.     var canvasData = tempContext.getImageData(0, 0, canvas.width, canvas.height);  
  60.        var binaryData = canvasData.data;  
  61.          
  62.        // Processing all the pixels  
  63.        gfilter.colorAdjustProcess(binaryData, len);  
  64.   
  65.        // Copying back canvas data to canvas  
  66.        tempContext.putImageData(canvasData, 0, 0);  
  67. }  
  68.   
  69. function blurImage()   
  70. {  
  71.     var canvas = document.getElementById("target");  
  72.     var len = canvas.width * canvas.height * 4;  
  73.     var canvasData = tempContext.getImageData(0, 0, canvas.width, canvas.height);  
  74.          
  75.        // Processing all the pixels  
  76.        gfilter.blurProcess(tempContext, canvasData);  
  77.   
  78.        // Copying back canvas data to canvas  
  79.        tempContext.putImageData(canvasData, 0, 0);  
  80. }  
  81.       
  82. function fudiaoImage()   
  83. {  
  84.     var canvas = document.getElementById("target");  
  85.     var len = canvas.width * canvas.height * 4;  
  86.     var canvasData = tempContext.getImageData(0, 0, canvas.width, canvas.height);  
  87.          
  88.        // Processing all the pixels  
  89.        gfilter.reliefProcess(tempContext, canvasData);  
  90.   
  91.        // Copying back canvas data to canvas  
  92.        tempContext.putImageData(canvasData, 0, 0);  
  93. }  
  94.   
  95. function kediaoImage()   
  96. {  
  97.     var canvas = document.getElementById("target");  
  98.     var len = canvas.width * canvas.height * 4;  
  99.     var canvasData = tempContext.getImageData(0, 0, canvas.width, canvas.height);  
  100.          
  101.        // Processing all the pixels  
  102.        gfilter.diaokeProcess(tempContext, canvasData);  
  103.   
  104.        // Copying back canvas data to canvas  
  105.        tempContext.putImageData(canvasData, 0, 0);  
  106. }  
  107.   
  108. function mirrorImage()   
  109. {  
  110.     var canvas = document.getElementById("target");  
  111.     var len = canvas.width * canvas.height * 4;  
  112.     var canvasData = tempContext.getImageData(0, 0, canvas.width, canvas.height);  
  113.          
  114.        // Processing all the pixels  
  115.        gfilter.mirrorProcess(tempContext, canvasData);  
  116.   
  117.        // Copying back canvas data to canvas  
  118.        tempContext.putImageData(canvasData, 0, 0);  
  119. }  
滤镜源代码(gloomyfishfilter.js):

 

 

[javascript] view plain copy
 
  1. var gfilter = {  
  2.     type: "canvas",  
  3.     name: "filters",  
  4.     author: "zhigang",  
  5.     getInfo: function () {  
  6.         return this.author + ' ' + this.type + ' ' + this.name;  
  7.     },  
  8.   
  9.     /** 
  10.      * invert color value of pixel, new pixel = RGB(255-r, 255-g, 255 - b) 
  11.      *  
  12.      * @param binaryData - canvas's imagedata.data 
  13.      * @param l - length of data (width * height of image data) 
  14.      */  
  15.     colorInvertProcess: function(binaryData, l) {  
  16.         for (var i = 0; i < l; i += 4) {  
  17.             var r = binaryData[i];  
  18.             var g = binaryData[i + 1];  
  19.             var b = binaryData[i + 2];  
  20.       
  21.             binaryData[i] = 255-r;  
  22.             binaryData[i + 1] = 255-g;  
  23.             binaryData[i + 2] = 255-b;  
  24.         }  
  25.     },  
  26.       
  27.     /** 
  28.      * adjust color values and make it more darker and gray... 
  29.      *  
  30.      * @param binaryData 
  31.      * @param l 
  32.      */  
  33.     colorAdjustProcess: function(binaryData, l) {  
  34.         for (var i = 0; i < l; i += 4) {  
  35.             var r = binaryData[i];  
  36.             var g = binaryData[i + 1];  
  37.             var b = binaryData[i + 2];  
  38.   
  39.             binaryData[i] = (r * 0.272) + (g * 0.534) + (b * 0.131);  
  40.             binaryData[i + 1] = (r * 0.349) + (g * 0.686) + (b * 0.168);  
  41.             binaryData[i + 2] = (r * 0.393) + (g * 0.769) + (b * 0.189);  
  42.         }  
  43.     },  
  44.       
  45.     /** 
  46.      * deep clone image data of canvas 
  47.      *  
  48.      * @param context 
  49.      * @param src 
  50.      * @returns 
  51.      */  
  52.     copyImageData: function(context, src)  
  53.     {  
  54.         var dst = context.createImageData(src.width, src.height);  
  55.         dst.data.set(src.data);  
  56.         return dst;  
  57.     },  
  58.       
  59.     /** 
  60.      * convolution - keneral size 5*5 - blur effect filter(模糊效果) 
  61.      *  
  62.      * @param context 
  63.      * @param canvasData 
  64.      */  
  65.     blurProcess: function(context, canvasData) {  
  66.         console.log("Canvas Filter - blur process");  
  67.         var tempCanvasData = this.copyImageData(context, canvasData);  
  68.         var sumred = 0.0, sumgreen = 0.0, sumblue = 0.0;  
  69.         for ( var x = 0; x < tempCanvasData.width; x++) {      
  70.             for ( var y = 0; y < tempCanvasData.height; y++) {      
  71.       
  72.                 // Index of the pixel in the array      
  73.                 var idx = (x + y * tempCanvasData.width) * 4;         
  74.                 for(var subCol=-2; subCol<=2; subCol++) {  
  75.                     var colOff = subCol + x;  
  76.                     if(colOff <0 || colOff >= tempCanvasData.width) {  
  77.                         colOff = 0;  
  78.                     }  
  79.                     for(var subRow=-2; subRow<=2; subRow++) {  
  80.                         var rowOff = subRow + y;  
  81.                         if(rowOff < 0 || rowOff >= tempCanvasData.height) {  
  82.                             rowOff = 0;  
  83.                         }  
  84.                         var idx2 = (colOff + rowOff * tempCanvasData.width) * 4;      
  85.                         var r = tempCanvasData.data[idx2 + 0];      
  86.                         var g = tempCanvasData.data[idx2 + 1];      
  87.                         var b = tempCanvasData.data[idx2 + 2];  
  88.                         sumred += r;  
  89.                         sumgreen += g;  
  90.                         sumblue += b;  
  91.                     }  
  92.                 }  
  93.                   
  94.                 // calculate new RGB value  
  95.                 var nr = (sumred / 25.0);  
  96.                 var ng = (sumgreen / 25.0);  
  97.                 var nb = (sumblue / 25.0);  
  98.                   
  99.                 // clear previous for next pixel point  
  100.                 sumred = 0.0;  
  101.                 sumgreen = 0.0;  
  102.                 sumblue = 0.0;  
  103.                   
  104.                 // assign new pixel value      
  105.                 canvasData.data[idx + 0] = nr; // Red channel      
  106.                 canvasData.data[idx + 1] = ng; // Green channel      
  107.                 canvasData.data[idx + 2] = nb; // Blue channel      
  108.                 canvasData.data[idx + 3] = 255; // Alpha channel      
  109.             }  
  110.         }  
  111.     },  
  112.       
  113.     /** 
  114.      * after pixel value - before pixel value + 128 
  115.      * 浮雕效果 
  116.      */  
  117.     reliefProcess: function(context, canvasData) {  
  118.         console.log("Canvas Filter - relief process");  
  119.         var tempCanvasData = this.copyImageData(context, canvasData);  
  120.         for ( var x = 1; x < tempCanvasData.width-1; x++)   
  121.         {      
  122.             for ( var y = 1; y < tempCanvasData.height-1; y++)  
  123.             {      
  124.       
  125.                 // Index of the pixel in the array      
  126.                 var idx = (x + y * tempCanvasData.width) * 4;         
  127.                 var bidx = ((x-1) + y * tempCanvasData.width) * 4;  
  128.                 var aidx = ((x+1) + y * tempCanvasData.width) * 4;  
  129.                   
  130.                 // calculate new RGB value  
  131.                 var nr = tempCanvasData.data[aidx + 0] - tempCanvasData.data[bidx + 0] + 128;  
  132.                 var ng = tempCanvasData.data[aidx + 1] - tempCanvasData.data[bidx + 1] + 128;  
  133.                 var nb = tempCanvasData.data[aidx + 2] - tempCanvasData.data[bidx + 2] + 128;  
  134.                 nr = (nr < 0) ? 0 : ((nr >255) ? 255 : nr);  
  135.                 ng = (ng < 0) ? 0 : ((ng >255) ? 255 : ng);  
  136.                 nb = (nb < 0) ? 0 : ((nb >255) ? 255 : nb);  
  137.                   
  138.                 // assign new pixel value      
  139.                 canvasData.data[idx + 0] = nr; // Red channel      
  140.                 canvasData.data[idx + 1] = ng; // Green channel      
  141.                 canvasData.data[idx + 2] = nb; // Blue channel      
  142.                 canvasData.data[idx + 3] = 255; // Alpha channel      
  143.             }  
  144.         }  
  145.     },  
  146.       
  147.     /** 
  148.      *  before pixel value - after pixel value + 128 
  149.      *  雕刻效果 
  150.      *  
  151.      * @param canvasData 
  152.      */  
  153.     diaokeProcess: function(context, canvasData) {  
  154.         console.log("Canvas Filter - process");  
  155.         var tempCanvasData = this.copyImageData(context, canvasData);  
  156.         for ( var x = 1; x < tempCanvasData.width-1; x++)   
  157.         {      
  158.             for ( var y = 1; y < tempCanvasData.height-1; y++)  
  159.             {      
  160.       
  161.                 // Index of the pixel in the array      
  162.                 var idx = (x + y * tempCanvasData.width) * 4;         
  163.                 var bidx = ((x-1) + y * tempCanvasData.width) * 4;  
  164.                 var aidx = ((x+1) + y * tempCanvasData.width) * 4;  
  165.                   
  166.                 // calculate new RGB value  
  167.                 var nr = tempCanvasData.data[bidx + 0] - tempCanvasData.data[aidx + 0] + 128;  
  168.                 var ng = tempCanvasData.data[bidx + 1] - tempCanvasData.data[aidx + 1] + 128;  
  169.                 var nb = tempCanvasData.data[bidx + 2] - tempCanvasData.data[aidx + 2] + 128;  
  170.                 nr = (nr < 0) ? 0 : ((nr >255) ? 255 : nr);  
  171.                 ng = (ng < 0) ? 0 : ((ng >255) ? 255 : ng);  
  172.                 nb = (nb < 0) ? 0 : ((nb >255) ? 255 : nb);  
  173.                   
  174.                 // assign new pixel value      
  175.                 canvasData.data[idx + 0] = nr; // Red channel      
  176.                 canvasData.data[idx + 1] = ng; // Green channel      
  177.                 canvasData.data[idx + 2] = nb; // Blue channel      
  178.                 canvasData.data[idx + 3] = 255; // Alpha channel      
  179.             }  
  180.         }  
  181.     },  
  182.       
  183.     /** 
  184.      * mirror reflect 
  185.      *  
  186.      * @param context 
  187.      * @param canvasData 
  188.      */  
  189.     mirrorProcess : function(context, canvasData) {  
  190.         console.log("Canvas Filter - process");  
  191.         var tempCanvasData = this.copyImageData(context, canvasData);  
  192.         for ( var x = 0; x < tempCanvasData.width; x++) // column  
  193.         {      
  194.             for ( var y = 0; y < tempCanvasData.height; y++) // row  
  195.             {      
  196.       
  197.                 // Index of the pixel in the array      
  198.                 var idx = (x + y * tempCanvasData.width) * 4;         
  199.                 var midx = (((tempCanvasData.width -1) - x) + y * tempCanvasData.width) * 4;  
  200.                   
  201.                 // assign new pixel value      
  202.                 canvasData.data[midx + 0] = tempCanvasData.data[idx + 0]; // Red channel      
  203.                 canvasData.data[midx + 1] = tempCanvasData.data[idx + 1]; ; // Green channel      
  204.                 canvasData.data[midx + 2] = tempCanvasData.data[idx + 2]; ; // Blue channel      
  205.                 canvasData.data[midx + 3] = 255; // Alpha channel      
  206.             }  
  207.         }  
  208.     },  
  209. }; 
posted @ 2016-11-04 14:16  奋斗蚁  阅读(1115)  评论(0编辑  收藏  举报