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

2024-05-05 09:48

本文主要是介绍[前端] canvas进阶之常用滤镜,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

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

 

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

 

欢迎关注技术开发分享录:http://fenxianglu.cn/

 

这篇关于[前端] canvas进阶之常用滤镜的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/961409

相关文章

Vue3 的 shallowRef 和 shallowReactive:优化性能

大家对 Vue3 的 ref 和 reactive 都很熟悉,那么对 shallowRef 和 shallowReactive 是否了解呢? 在编程和数据结构中,“shallow”(浅层)通常指对数据结构的最外层进行操作,而不递归地处理其内部或嵌套的数据。这种处理方式关注的是数据结构的第一层属性或元素,而忽略更深层次的嵌套内容。 1. 浅层与深层的对比 1.1 浅层(Shallow) 定义

HarmonyOS学习(七)——UI(五)常用布局总结

自适应布局 1.1、线性布局(LinearLayout) 通过线性容器Row和Column实现线性布局。Column容器内的子组件按照垂直方向排列,Row组件中的子组件按照水平方向排列。 属性说明space通过space参数设置主轴上子组件的间距,达到各子组件在排列上的等间距效果alignItems设置子组件在交叉轴上的对齐方式,且在各类尺寸屏幕上表现一致,其中交叉轴为垂直时,取值为Vert

Spring Security 从入门到进阶系列教程

Spring Security 入门系列 《保护 Web 应用的安全》 《Spring-Security-入门(一):登录与退出》 《Spring-Security-入门(二):基于数据库验证》 《Spring-Security-入门(三):密码加密》 《Spring-Security-入门(四):自定义-Filter》 《Spring-Security-入门(五):在 Sprin

JS常用组件收集

收集了一些平时遇到的前端比较优秀的组件,方便以后开发的时候查找!!! 函数工具: Lodash 页面固定: stickUp、jQuery.Pin 轮播: unslider、swiper 开关: switch 复选框: icheck 气泡: grumble 隐藏元素: Headroom

这15个Vue指令,让你的项目开发爽到爆

1. V-Hotkey 仓库地址: github.com/Dafrok/v-ho… Demo: 戳这里 https://dafrok.github.io/v-hotkey 安装: npm install --save v-hotkey 这个指令可以给组件绑定一个或多个快捷键。你想要通过按下 Escape 键后隐藏某个组件,按住 Control 和回车键再显示它吗?小菜一碟: <template

【 html+css 绚丽Loading 】000046 三才归元阵

前言:哈喽,大家好,今天给大家分享html+css 绚丽Loading!并提供具体代码帮助大家深入理解,彻底掌握!创作不易,如果能帮助到大家或者给大家一些灵感和启发,欢迎收藏+关注哦 💕 目录 📚一、效果📚二、信息💡1.简介:💡2.外观描述:💡3.使用方式:💡4.战斗方式:💡5.提升:💡6.传说: 📚三、源代码,上代码,可以直接复制使用🎥效果🗂️目录✍️

【前端学习】AntV G6-08 深入图形与图形分组、自定义节点、节点动画(下)

【课程链接】 AntV G6:深入图形与图形分组、自定义节点、节点动画(下)_哔哩哔哩_bilibili 本章十吾老师讲解了一个复杂的自定义节点中,应该怎样去计算和绘制图形,如何给一个图形制作不间断的动画,以及在鼠标事件之后产生动画。(有点难,需要好好理解) <!DOCTYPE html><html><head><meta charset="UTF-8"><title>06

Java进阶13讲__第12讲_1/2

多线程、线程池 1.  线程概念 1.1  什么是线程 1.2  线程的好处 2.   创建线程的三种方式 注意事项 2.1  继承Thread类 2.1.1 认识  2.1.2  编码实现  package cn.hdc.oop10.Thread;import org.slf4j.Logger;import org.slf4j.LoggerFactory

【C++】_list常用方法解析及模拟实现

相信自己的力量,只要对自己始终保持信心,尽自己最大努力去完成任何事,就算事情最终结果是失败了,努力了也不留遗憾。💓💓💓 目录   ✨说在前面 🍋知识点一:什么是list? •🌰1.list的定义 •🌰2.list的基本特性 •🌰3.常用接口介绍 🍋知识点二:list常用接口 •🌰1.默认成员函数 🔥构造函数(⭐) 🔥析构函数 •🌰2.list对象

常用的jdk下载地址

jdk下载地址 安装方式可以看之前的博客: mac安装jdk oracle 版本:https://www.oracle.com/java/technologies/downloads/ Eclipse Temurin版本:https://adoptium.net/zh-CN/temurin/releases/ 阿里版本: github:https://github.com/