canvas图像处理汇总
一、canvas的情况
canvas自从出来了之后,在前端的图像处理上面提供了各种各样的遍历,虽然很多的操作其实都是要应用到算法的,但是这个也给前端提供了很多的可能性,其中最终要的一个canvas函数(至少我认为)就是getImageData,这个函数可以提取图像每个像素的RGBA值。因为有这个函数所有才有丰富多彩的canvas图像处理。
二、预备知识
2.1 获取一个canvas对象
<canvas id="test"></canvas> <script>var test = document.querySelector("#test");// 方法一var test_1=document.getElementById("test");// 方法二 console.log(test);console.log(test_1); </script>
2.2 创建一个画布的空间类型(2D,3D)
创建一个2D的画布
var ctx = test.getContext("2d");
2.3 getImageData对象
getImageData对象可以获取画布中的图片对应的所有像素的RGBA值,这个有利于我们对图片进行重新的计算。在使用这个属性的时候,需要配置好HTTP的访问环境。
2.4 Uint8ClampedArray
这个代表的是一个无类型8位的字符串,也就是说明最多存储到255
2.5 Uint8ClampedArray与getImageData对象
Uint8ClampedArray包含在getImageData对象中,getImageData除了有Uint8ClampedArray之外,还有获取图片数据的长度和宽度。
三、多种图片效果canvas实现
1. 原图
2. 反色(负片)效果
3. 去色效果
4. 单色效果
5. 中国版画效果
6. 高斯模糊效果
7. 浮雕效果与刻雕效果
3.1 原图
通过canvas来渲染原图,首选我们在网上随意找一张图片。
·
window.onload = function () {var img = new Image();img.src = "rx.jpg";// 加载完成图片之后才能够执行canvas的操作img.onload = function () {var canvas = document.querySelector("#canvas");var cxt = canvas.getContext("2d");canvas.width=293;canvas.height=220;cxt.drawImage(img, 0, 0, 293, 220);}}
其中canvas的width,height属性都是必须要设置的,不设置的话,canvas会采用默认的width=300,height=150来设置图片。
3.2 反色(负片)效果
图片反色的原理其实很简单不多做解释:将图片中的每一个元素进行如下的公式运算就可以得到最终的结果
window.onload = function () {var img = new Image();img.src = "rx.jpg";img.onload = function () {var canvas = document.querySelector("#canvas");var cxt = canvas.getContext("2d");canvas.width = 293;canvas.height = 220;cxt.drawImage(img, 0, 0, canvas.width, canvas.height);var imageData = cxt.getImageData(0, 0, canvas.width, canvas.height);var imageData_length = imageData.data.length / 4;// 解析之后进行算法运算for (var i = 0; i < imageData_length; i++) {imageData.data[i * 4] = 255 - imageData.data[i * 4];imageData.data[i * 4 + 1] = 255 - imageData.data[i * 4 + 1];imageData.data[i * 4 + 2] = 255 - imageData.data[i * 4 + 2];}cxt.putImageData(imageData, 0, 0);}}
运行之后的效果如下:
3.3 去色效果
这里说的去色效果与第二种效果不同的是,去色效果相当于就是老旧相机拍出来的黑白照片。
要得到去色效果的照片有很多种方法,但是卤煮比较推崇的做法是采用基于人眼感觉的加权平均数来实现,这个算法的原理是采用人眼对RGB不同颜色的敏感程度不同,然后通过得出的加权平均数来运算出最后的结果
Gray = (Red * 0.3 + Green * 0.59 + Blue * 0.11)
代码如下实现:
window.onload = function () {var img = new Image();img.src = "rx.jpg";img.onload = function () {var canvas = document.querySelector("#canvas");var cxt = canvas.getContext("2d");canvas.width = 293;canvas.height = 220;cxt.drawImage(img, 0, 0, canvas.width, canvas.height);var imageData = cxt.getImageData(0, 0, canvas.width, canvas.height);var imageData_length = imageData.data.length / 4;// 解析之后进行算法运算for (var i = 0; i < imageData_length; i++) {var red = imageData.data[i * 4];var green = imageData.data[i * 4 + 1];var blue = imageData.data[i * 4 + 2];var gray = 0.3 * red + 0.59 * green + 0.11 * blue;imageData.data[i * 4] = gray;imageData.data[i * 4 + 1] = gray;imageData.data[i * 4 + 2] = gray;}cxt.putImageData(imageData, 0, 0);}}
运行效果如下:
3.4 单色效果
单颜色效果原理就是将当前像素的其他色值去除。
假设我们要实现的单颜色效果是红色,那么实现的代码如下:
window.onload = function () {var img = new Image();img.src = "rx.jpg";img.onload = function () {var canvas = document.querySelector("#canvas");var cxt = canvas.getContext("2d");canvas.width = 293;canvas.height = 220;cxt.drawImage(img, 0, 0, canvas.width, canvas.height);var imageData = cxt.getImageData(0, 0, canvas.width, canvas.height);var imageData_length = imageData.data.length / 4;// 解析之后进行算法运算for (var i = 0; i < imageData_length; i++) {imageData.data[i * 4 + 1] = 0;imageData.data[i * 4 + 2] = 0;}cxt.putImageData(imageData, 0, 0);}}
效果图:
3.5 中国版画效果
中国版画不同于去色和反色的效果,在中国版画的效果中除了黑就是白色,不存在其他的颜色,下面就是一张传统的中国版画的效果。
这个的实现算法比较的灵活一般是根据你要得到的效果来进行参数配置的,原理就是通过判断当前元素的色值是否高于这个给定值,高于我们就显示为黑色,小于我们就显示为白色这样的一种方法来实现的。
按照卤煮一般的设置值来说会设置为126.因为126是2的8次方的中间数。相对来说比较的对称
实现的代码如下:
window.onload = function () {var img = new Image();img.src = "rx.jpg";img.onload = function () {var canvas = document.querySelector("#canvas");var cxt = canvas.getContext("2d");canvas.width = 293;canvas.height = 220;cxt.drawImage(img, 0, 0, canvas.width, canvas.height);var imageData = cxt.getImageData(0, 0, canvas.width, canvas.height);var imageData_length = imageData.data.length / 4;// 解析之后进行算法运算for (var i = 0; i < imageData_length; i++) {var red = imageData.data[i * 4];var green = imageData.data[i * 4 + 1];var blue = imageData.data[i * 4 + 2];var gray = 0.3 * red + 0.59 * green + 0.11 * blue;var new_black;if (gray > 126) {new_black = 255;} else {new_black = 0;}imageData.data[i * 4] = new_black;imageData.data[i * 4 + 1] = new_black;imageData.data[i * 4 + 2] = new_black;}cxt.putImageData(imageData, 0, 0);}}
运行的效果如下:
如果是我们要渲染更多的黑颜色的话,我们应该要将值调高,反之将其调低,下面我们把值调到150运行一下:
3.6 高斯模糊效果
高斯模糊是一种两维的卷积模糊操作,简单的介绍就是通过让图片的每个像素与四周的像素按照某种权重进行分布求值,要了解具体的同学可以戳戳这里。
这里我们就展示结论,推导不做介绍(二维高斯分布函数):
我们直接贴出实现的代码:
function gaussBlur(imgData) {console.log(imgData);var pixes = imgData.data;var width = imgData.width;var height = imgData.height;var gaussMatrix = [],gaussSum = 0,x, y,r, g, b, a,i, j, k, len;var radius = 30;var sigma = 5;a = 1 / (Math.sqrt(2 * Math.PI) * sigma);b = -1 / (2 * sigma * sigma);//生成高斯矩阵for (i = 0, x = -radius; x <= radius; x++, i++){g = a * Math.exp(b * x * x);gaussMatrix[i] = g;gaussSum += g;}//归一化, 保证高斯矩阵的值在[0,1]之间for (i = 0, len = gaussMatrix.length; i < len; i++) {gaussMatrix[i] /= gaussSum; }//x 方向一维高斯运算for (y = 0; y < height; y++) {for (x = 0; x < width; x++) {r = g = b = a = 0;gaussSum = 0;for(j = -radius; j <= radius; j++){k = x + j;if(k >= 0 && k < width){//确保 k 没超出 x 的范围//r,g,b,a 四个一组i = (y * width + k) * 4;r += pixes[i] * gaussMatrix[j + radius];g += pixes[i + 1] * gaussMatrix[j + radius];b += pixes[i + 2] * gaussMatrix[j + radius];// a += pixes[i + 3] * gaussMatrix[j];gaussSum += gaussMatrix[j + radius];}}i = (y * width + x) * 4;// 除以 gaussSum 是为了消除处于边缘的像素, 高斯运算不足的问题// console.log(gaussSum)pixes[i] = r / gaussSum;pixes[i + 1] = g / gaussSum;pixes[i + 2] = b / gaussSum;// pixes[i + 3] = a ; }}//y 方向一维高斯运算for (x = 0; x < width; x++) {for (y = 0; y < height; y++) {r = g = b = a = 0;gaussSum = 0;for(j = -radius; j <= radius; j++){k = y + j;if(k >= 0 && k < height){//确保 k 没超出 y 的范围i = (k * width + x) * 4;r += pixes[i] * gaussMatrix[j + radius];g += pixes[i + 1] * gaussMatrix[j + radius];b += pixes[i + 2] * gaussMatrix[j + radius];// a += pixes[i + 3] * gaussMatrix[j];gaussSum += gaussMatrix[j + radius];}}i = (y * width + x) * 4;pixes[i] = r / gaussSum;pixes[i + 1] = g / gaussSum;pixes[i + 2] = b / gaussSum;}}console.log(imgData);return imgData; }
运行之后的效果如下:
3.7 浮雕效果与刻雕效果
这里要感谢CSDN的算法专家gloomyfish,他的博文给我提供了一个好的思路,同时根据他的一个代码逻辑我们可以得出如下的公式:
(C常量,Xa后一个像素的RGB,Xb前一个像素的RGB)
其中color代表的是最后的色值,Xa和Xb代表的是当前像素前后两点的RGB(中的某一个值),C代表的是一个常量【根据你的具体需要来定】
原理就是将某个像素与周边的差值较大的检测出来,然后替换成为255,一般我们将这个常量C设置成为128【255的一半】
/*** after pixel value - before pixel value + 128* 代码引用自 gloomyfish* 浮雕效果*/reliefProcess: function(context, canvasData) {//caontext 画布对象 document.querySelector().getContext("2d");// conavas document.querySelector().getContext("2d").getImageData();console.log("Canvas Filter - relief process");var tempCanvasData = this.copyImageData(context, canvasData);for ( var x = 0; x < tempCanvasData.width-1; x++){for ( var y = 0; y < tempCanvasData.height-1; y++){// Index of the pixel in the array var idx = (x + y * tempCanvasData.width) * 4;var bidx = ((x-1) + y * tempCanvasData.width) * 4;var aidx = ((x+1) + y * tempCanvasData.width) * 4;// calculate new RGB valuevar nr = tempCanvasData.data[aidx + 0] - tempCanvasData.data[bidx + 0] + 128;var ng = tempCanvasData.data[aidx + 1] - tempCanvasData.data[bidx + 1] + 128;var nb = tempCanvasData.data[aidx + 2] - tempCanvasData.data[bidx + 2] + 128;nr = (nr < 0) ? 0 : ((nr >255) ? 255 : nr);ng = (ng < 0) ? 0 : ((ng >255) ? 255 : ng);nb = (nb < 0) ? 0 : ((nb >255) ? 255 : nb);// assign new pixel value canvasData.data[idx + 0] = nr; // Red channel canvasData.data[idx + 1] = ng; // Green channel canvasData.data[idx + 2] = nb; // Blue channel canvasData.data[idx + 3] = 255; // Alpha channel }}},
运行的图像如下:
其中常量的数值越大,浮雕的颜色越浅,反之加深。我们把它设置到50看下效果:
刻雕效果与浮雕效果基本一样,就是要调整公式里面的Xa和Xb的位置,调整如下:
四、小结
由于canvas涉及到的知识点比较的深奥,所以里面有很多的内容没法再这里一一的进行说明,这一篇文章也就是对于canvas实际应用的一个简单的说明,在图形学方面,磨皮处理和高通滤波,低通滤波等等方面的处理还没有实现,在一些粒子化,动画,碰撞方面也不能一一道来,深表遗憾
canvas图像处理汇总相关推荐
- Canvas知识点汇总
本文主要记录Canvas基础知识汇总. 1.Canvas定义 <canvas> 元素是HTML5中的新元素,通过它可以在网页中绘制出所需的图形.<canvas>标签只是图形的容 ...
- 微信小游戏开发Canvas资源汇总
Demo: 微信小程序demo组件:股票分时图 微信小程序小组件:仿直播点赞气泡效果,基于Canvas 优质demo推荐:二维码生成器:使用canvas与纯JS版二维码生成 微信小程序学习用完整dem ...
- canvas学习和滤镜实现
最近学习了 HTML5 中的重头戏-- canvas .利用 canvas,前端人员可以很轻松地.进行图像处理.其 API 繁多,这次主要学习常用的 API,并且完成以下两个代码: 实现去色滤镜 实现 ...
- canvas图片处理
源网址:https://www.cnblogs.com/st-leslie/p/8317850.html?utm_source=debugrun&utm_medium=referral 一.c ...
- html5 滤镜代码,canvas学习和滤镜实现代码
在这个数码产品泛滥的时代里,拍照已经成为生活不可或缺的一部分,不管是居家,踏青,还是远途旅行,总会拍一些美美的照片.但相机直接拍出来的照片往往和我们的心理预期有一定的差距,那么怎么减小这种差距呢?答案 ...
- 基于html5的矢量图绘制方法研究,基于HTML5Canvas技术的在线图像处理方法的研究...
摘要: 本文主要对基于HTML5Canvas技术的在线图像处理方法进行探讨和研究. 随着网页技术的飞速发展,在线的应用程序越来越受到用户的欢迎,很多业余摄影爱好者开始采用在线的图像处理软件来对照片进行 ...
- android 有效载荷大图,避OOM
我们的项目往往会载入图片.有时,承担太多,再装图片,它导致了非常小的程序卡,而在铅oom从而导致异常app再见,今天翻译google官方网站,它已经做了很好的图像处理汇总,由于Google我们已经给解 ...
- Silverlight/Windows8/WPF/WP7/HTML5周学习导读(9月17日-9月23日)
Silverlight/Windows8/WPF/WP7/HTML5周学习导读(9月17日-9月23日) 本周Silverlight学习资源更新 Silverlight动画设计中对平移动画的一点体会 ...
- 分享Silverlight/WPF/Windows Phone/HTML5一周学习导读(1月9日-1月15日)
分享Silverlight/WPF/Windows Phone/HTML5一周学习导读(1月9日-1月15日) 本周Silverlight学习资源更新 Silverlight4Beta之Binding ...
最新文章
- 云原生微服务技术趋势解读
- 浅谈Android系统开发中LOG的使用
- O’Reilly发布“微服务成熟度状态”报告:微服务是成功的
- Luogu P3830 [SHOI2012]随机树 | 期望 DP
- Oracle 该用户下所有的表
- 阿里云数据库开源发布:PolarDB三节点高可用的功能特性和关键技术
- RHEL5实现YUM本地源的配置
- swagger文档配置
- 【翻译】Vue.js中的computed是如何工作的
- 给“网吧”做管理系统
- ENVI/IDL编程:相对辐射校正-直方图匹配
- 算法导论答案 16.2-2 0-1背包问题的动态规划算法
- KEIL4与KEIL5护眼配色方案
- 方法、方法的重载(Overload)与重写(Override)
- 位运算中的一些数学原理
- big O notation - 大 O 表示法
- VScode已经设置了默认浏览器依然不成功原因
- 文远知行杯广东工业大学第十六届程序设计竞赛 E爬塔
- 用js实现背景颜色改变
- 学习随记三十一——递归实现二叉查找树