zoukankan      html  css  js  c++  java
  • 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.     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. }; 
  • 相关阅读:
    AngularJs+bootstrap搭载前台框架——准备工作
    AngularJs+bootstrap搭载前台框架——基础页面
    AngularJs调用Restful实现CRUD
    用AngularJs制作单页面应用
    Unity3D中使用Projector生成阴影
    Linux OpenGL 实践篇-16 文本绘制
    leetcode 233. 数字1的个数
    leetcode 189. 轮转数组
    leetcode 127 单词接龙
    leetcode 4.两个排序数组的中位数
  • 原文地址:https://www.cnblogs.com/Jasonellen/p/6030112.html
Copyright © 2011-2022 走看看