js canvas画布实现高斯模糊效果


Posted in Javascript onNovember 27, 2018

最近项目中有一个需求是实现图片的局部模糊效果,看上去一个挺难的效果。在实现局部模糊效果前,首先能够实现全部模糊。经过和度娘的一番较劲后,找到了一个不错的案例,然后在他的基础上,经过一番修改,和备注,实现了当前的案例:

js canvas画布实现高斯模糊效果

<!doctype html>
<html lang="zh">
<head>
 <meta charset="UTF-8">
 <meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
 <meta http-equiv="X-UA-Compatible" content="ie=edge">
 <title>canvas画布的高斯模糊效果</title>
</head>
<body>
<canvas id="canvas"></canvas>
</body>
<script>
 var canvas = document.getElementById('canvas');
 var ctx = canvas.getContext('2d');
 let img = new Image();
 //这里直接修改图片的路径
 img.src = "636753681750720000/Block/preview.jpg";
 img.onload = function () {
 //设置canvas的宽高
 canvas.height = img.height;
 canvas.width = img.width;
 //将图像绘制到canvas上面
 ctx.drawImage(img, 0, 0, img.width, img.height);
 //从画布获取一半图像
 var data = ctx.getImageData(0, 0, img.width/2, img.height);
 //将图像数据进行高斯模糊 data.data是一个数组,每四个值代表一个像素点的rgba的值,data.width data.height 分别代表图像数据的宽高
 var emptyData = gaussBlur(data);
 //将模糊的图像数据再渲染到画布上面
 ctx.putImageData(emptyData, 0, 0);
 };

 function gaussBlur(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 = 10;
 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;
  }
 }
 return imgData;
 }
</script>
</html>

代码不多,大家直接copy一下,运行好了。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
JAVASCRIPT  THIS详解 面向对象
Mar 25 Javascript
仅用[]()+!等符号就足以实现几乎任意Javascript代码
Mar 01 Javascript
13个绚丽的Jquery 界面设计网站推荐
Sep 28 Javascript
JavaScript中解决多浏览器兼容性23个问题的快速解决方法
May 19 Javascript
浅谈js图片前端预览之filereader和window.URL.createObjectURL
Jun 30 Javascript
express文件上传中间件Multer详解
Oct 24 Javascript
layer弹出层中H5播放器全屏出错的解决方法
Feb 21 Javascript
基于Vue过渡状态实例讲解
Sep 14 Javascript
Angular整合zTree的示例代码
Jan 24 Javascript
React 项目迁移 Webpack Babel7的实现
Sep 12 Javascript
vue中轮训器的使用
Jan 27 Javascript
一起来看看Vue的核心原理剖析
Mar 24 Vue.js
video.js 一个页面同时播放多个视频的实例代码
Nov 27 #Javascript
Vue数据双向绑定的深入探究
Nov 27 #Javascript
微信小程序带动画弹窗组件使用方法详解
Nov 27 #Javascript
微信小程序实现日历功能
Nov 27 #Javascript
微信小程序实现打卡日历功能
Sep 21 #Javascript
微信小程序实现时间预约功能
Nov 27 #Javascript
微信小程序使用component自定义toast弹窗效果
Nov 27 #Javascript
You might like
详解使用php调用微信接口上传永久素材
2017/04/11 PHP
php数组指针函数功能及用法示例
2020/02/11 PHP
JQuery.uploadify 上传文件插件的使用详解 for ASP.NET
2010/01/22 Javascript
web的各种前端打印方法之jquery打印插件PrintArea实现网页打印
2013/01/09 Javascript
使用js操作cookie的一点小收获分享
2013/09/03 Javascript
B/S模式项目中常用的javascript汇总
2013/12/17 Javascript
javascript中Date format(js日期格式化)方法小结
2015/12/17 Javascript
JavaScript必知必会(三) String .的方法来自何方
2016/06/08 Javascript
jquery事件与绑定事件
2017/03/16 Javascript
vue2.0构建单页应用最佳实战
2017/04/01 Javascript
一文让你彻底搞清楚javascript中的require、import与export
2017/09/24 Javascript
AngularJS实现的输入框字数限制提醒功能示例
2017/10/26 Javascript
axios发送post请求springMVC接收不到参数的解决方法
2018/03/05 Javascript
Element input树型下拉框的实现代码
2018/12/21 Javascript
Vue实战教程之仿肯德基宅急送App
2019/07/19 Javascript
python发布模块的步骤分享
2014/02/21 Python
python实现将pvr格式转换成pvr.ccz的方法
2015/04/28 Python
Python实现的朴素贝叶斯分类器示例
2018/01/06 Python
详解Django 中是否使用时区的区别
2018/06/14 Python
使用 Python 实现简单的 switch/case 语句的方法
2018/09/17 Python
python pickle存储、读取大数据量列表、字典数据的方法
2019/07/07 Python
Python使用lambda表达式对字典排序操作示例
2019/07/25 Python
调试Django时打印SQL语句的日志代码实例
2019/09/12 Python
浅谈Python描述数据结构之KMP篇
2020/09/06 Python
详解Css3新特性应用之过渡与动画
2017/01/10 HTML / CSS
初探CSS3中的calc()功能
2015/07/14 HTML / CSS
员工年终演讲稿
2014/01/03 职场文书
宿舍违规用电检讨书
2014/02/16 职场文书
党性锻炼的心得体会
2014/09/03 职场文书
大学推普周活动总结
2015/05/07 职场文书
工资证明格式模板
2015/06/12 职场文书
教师见习总结范文
2015/06/23 职场文书
在前女友婚礼上,用Python破解了现场的WIFI还把名称改成了
2021/05/28 Python
MySQL常见优化方案汇总
2022/01/18 MySQL
MySQL库表太大怎么办? 数据库分库分表项目实践
2022/04/11 MySQL
Oracle删除归档日志及添加定时任务
2022/06/28 Oracle