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

[前端] canvas进阶之常用滤镜在操作之前先上一张初始预览图 页面的布局结果就是这样 然后就是对各种滤镜效果的转换 主要的实现原理是改变像素 rgb 的值 接下来进入正题 进入代码操作 HTML 布局 div style overflow hidden div

大家好,我是讯享网,很高兴认识大家。

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


讯享网

 

主要的实现原理是改变像素 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/

 

小讯
上一篇 2025-03-02 19:00
下一篇 2025-02-27 15:57

相关推荐

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容,请联系我们,一经查实,本站将立刻删除。
如需转载请保留出处:https://51itzy.com/kjqy/68146.html