[前端] canvas进阶之常用滤镜

来源:互联网 发布:淘宝店茶叶招牌 编辑:程序博客网 时间:2024/06/05 20:18

在操作之前先上一张初始预览图,页面的布局结果就是这样,然后就是对各种滤镜效果的转换



主要的实现原理是改变像素 rgb的值



接下来进入正题,进入代码操作

HTML布局:

<div style="overflow: hidden;">    <canvas id="canvasa" width="455" height="248" style="display:block;float:left;border:1px solid #aaa;">    </canvas>    <canvas id="canvasb" width="455" height="248" style="display:block;float:left;border:1px solid #aaa;">    </canvas></div><div style=" margin-top:20px;font-size:20px;">    <a href = "javascript:greyEffect()" >灰度</a>    <a href = "javascript:blackEffect()" >黑白</a>    <a href = "javascript:reverseEffect()" >反色</a>    <a href = "javascript:blurEffect()" >模糊</a>    <a href = "javascript:mosaicEffect()" >像素化</a></div>

JS脚本:

a、初始化

var canvasa = document.getElementById("canvasa");var contexta = canvasa.getContext("2d");var canvasb = document.getElementById("canvasb");var contextb = canvasb.getContext("2d");var image = new Image();window.onload = function(){    image.src = "lol.jpg";    image.onload = function(){        contexta.drawImage( image , 0 , 0 , canvasa.width , canvasa.height );    }}

b、各种滤镜效果函数

1、灰度滤镜

function greyEffect(){    var imageData = contexta.getImageData( 0 , 0 , canvasa.width , canvasa.height );    var pixelData = imageData.data;    for( var i = 0 ; i < canvasb.width * canvasb.height ; i ++ ){        var r = pixelData[i*4+0];        var g = pixelData[i*4+1];        var b = pixelData[i*4+2];        var grey = r*0.3+g*0.59+b*0.11;        pixelData[i*4+0] = grey;        pixelData[i*4+1] = grey;        pixelData[i*4+2] = grey;    }    contextb.putImageData( imageData , 0 , 0 , 0 , 0 , canvasb.width , canvasb.height );}

效果:



2、黑白滤镜

function blackEffect(){    var imageData = contexta.getImageData( 0 , 0 , canvasa.width , canvasa.height );    var pixelData = imageData.data;    for( var i = 0 ; i < canvasb.width * canvasb.height ; i ++ ){        var r = pixelData[i*4+0];        var g = pixelData[i*4+1];        var b = pixelData[i*4+2];        var grey = r*0.3+g*0.59+b*0.11;        if(grey > 125){            pv = 255;        }        else{            pv = 0;        }        pixelData[i*4+0] = pv;        pixelData[i*4+1] = pv;        pixelData[i*4+2] = pv;    }    contextb.putImageData( imageData , 0 , 0 , 0 , 0 , canvasa.width , canvasa.height );}

效果:



3、反色滤镜

function reverseEffect(){    var imageData = contexta.getImageData( 0 , 0 , canvasa.width , canvasa.height );    var pixelData = imageData.data;    for( var i = 0 ; i < canvasb.width * canvasb.height ; i ++ ){        var r = pixelData[i*4+0];        var g = pixelData[i*4+1];        var b = pixelData[i*4+2];        pixelData[i*4+0] = 255 - r;        pixelData[i*4+1] = 255 - g;        pixelData[i*4+2] = 255 - b;    }    contextb.putImageData( imageData , 0 , 0 , 0 , 0 , canvasb.width , canvasb.height );}

效果:



4、模糊滤镜

function blurEffect(){    var tmpImageData = contexta.getImageData( 0 , 0 , canvasa.width , canvasa.height );    var tmpPixelData = tmpImageData.data;    var imageData = contexta.getImageData( 0 , 0 , canvasa.width , canvasa.height );    var pixelData = imageData.data;    var blurR = 3;    var totalnum = (2*blurR + 1)*(2*blurR + 1);    for( var i = blurR ; i < canvasb.height - blurR ; i ++ )        for( var j = blurR ; j < canvasb.width - blurR ; j ++ ){            var totalr = 0 , totalg = 0 , totalb = 0;            for( var dx = -blurR ; dx <= blurR ; dx ++ )                for( var dy = -blurR ; dy <= blurR ; dy ++ ){                    var x = i + dx;                    var y = j + dy;                    var p = x*canvasb.width + y;                    totalr += tmpPixelData[p*4+0];                    totalg += tmpPixelData[p*4+1];                    totalb += tmpPixelData[p*4+2];                }            var p = i*canvasb.width + j;            pixelData[p*4+0] = totalr / totalnum;            pixelData[p*4+1] = totalg / totalnum;            pixelData[p*4+2] = totalb / totalnum;        }    contextb.putImageData( imageData , 0 , 0 , 0 , 0 , canvasb.width , canvasb.height );}

效果:



5、像素化滤镜

function mosaicEffect(){    var tmpImageData = contexta.getImageData( 0 , 0 , canvasa.width , canvasa.height );    var tmpPixelData = tmpImageData.data;    var imageData = contexta.getImageData( 0 , 0 , canvasa.width , canvasa.height );    var pixelData = imageData.data;    var size = 16;    var totalnum = size*size;    for( var i = 0 ; i < canvasb.height ; i += size )        for( var j = 0 ; j < canvasb.width ; j += size ){            var totalr = 0 , totalg = 0 , totalb = 0;            for( var dx = 0 ; dx < size ; dx ++ )                for( var dy = 0 ; dy < size ; dy ++ ){                    var x = i + dx;                    var y = j + dy;                    var p = x*canvasb.width + y;                    totalr += tmpPixelData[p*4+0];                    totalg += tmpPixelData[p*4+1];                    totalb += tmpPixelData[p*4+2];                }            var p = i*canvasb.width+j;            var resr = totalr / totalnum;            var resg = totalg / totalnum;            var resb = totalb / totalnum;            for( var dx = 0 ; dx < size ; dx ++ )                for( var dy = 0 ; dy < size ; dy ++ ){                    var x = i + dx;                    var y = j + dy;                    var p = x*canvasb.width + y;                    pixelData[p*4+0] = resr;                    pixelData[p*4+1] = resg;                    pixelData[p*4+2] = resb;                }    }    contextb.putImageData( imageData , 0 , 0 , 0 , 0 , canvasb.width, canvasb.height );}

效果:



知识点:

1、putImageData(imgData, x, y, dirtyX, dirtyY, dirtyWidth, dirtyHeight) 方法参数详解

参数描述imgData规定要放回画布的 ImageData 对象。xImageData 对象左上角的 x 坐标,以像素计。yImageData 对象左上角的 y 坐标,以像素计。dirtyX可选。水平值(x),以像素计,在画布上放置图像的位置。dirtyY可选。水平值(y),以像素计,在画布上放置图像的位置。dirtyWidth可选。在画布上绘制图像所使用的宽度。dirtyHeight可选。在画布上绘制图像所使用的高度。

图解:



2、与之对应的是getImageData(x, y, width, height)

参数描述x开始复制的左上角位置的 x 坐标。y开始复制的左上角位置的 y 坐标。width将要复制的矩形区域的宽度。height将要复制的矩形区域的高度。

改变色相(代码不全):

var rgb = $(this).css('background-color');  // 获取背景rgb颜色var rgbArr = rgb.match(/\d+/g); // 转换成数组

/*  渲染表带颜色  @param rgbArr array (rgb颜色值) */this.renderColor = function(rgbArr) {    var canvas = document.getElementById('watchBandCanvas');    var ctx = canvas.getContext('2d');    var img = new Image();    img.src = $('.img-watch-band').attr('src');    img.onload = function() {        var width = img.width;        var height = img.height;        canvas.width = width;        canvas.height = height;        ctx.drawImage(img, 0, 0);        var imgData = ctx.getImageData(0, 0, width, height);        for( var i=0; i<imgData.data.length; i+=4){            imgData.data[i+0] = rgbArr[0] - imgData.data[i+0];            imgData.data[i+1] = rgbArr[1] - imgData.data[i+1];            imgData.data[i+2] = rgbArr[2] - imgData.data[i+2];        }        ctx.putImageData(imgData, 0, 0, 0, 0, width, height);    }}


谢谢关注!


0 0
原创粉丝点击