在操作之前先上一张初始预览图,页面的布局结果就是这样,然后就是对各种滤镜效果的转换
主要的实现原理是改变像素 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 对象。 |
x | ImageData 对象左上角的 x 坐标,以像素计。 |
y | ImageData 对象左上角的 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);
}
}
欢迎关注技术开发分享录:http://fenxianglu.cn/