查看效果请到 http://philippica.github.io/  点击blur

模糊效果比较好的应该是高斯模糊,一个点的值变成了以该点为圆心的一个圆内所有像素的加权平均,权重由二维正态分布计算出

以前用qt实现过一个高斯模糊,但是js的速度毕竟不能和c++比,为了实现一个比较好的效果,这里在效率和效果方面做了个折中,每一点的值等于以这个点为中心的正方形内所有像素值的平均

这样的优点是计算速度快,矩阵天然的存着正方形,所以通过一个O(canvasWidth * canvasHeight)的预处理,接下来即可迅速地得到每个像素的值

具体方法应该是acm里用烂的方法,sum[i][j]存着以(i,j)为右下角的到左上角画布中所有该通道值的和,于是画布中任意矩形的和都可以用一个类似容斥的方法O(1)得到

预处理的代码:

     var ppImgData = context.getImageData(0, 0, ppCanvasWidth, ppCanvasHeight);
var ppData = ppImgData.data;
var ppTemp = ppData;
var radius = 0;
var length = ppData.length;
$('#range').attr("value", 0);
for(var i = 0; i < ppCanvasHeight; i++)
{
for(var j = 0; j < ppCanvasWidth; j++)
{
var position = i * ppCanvasWidth + j;
var x = (position) * 4;
sumR[position] = ppData[x];
sumG[position] = ppData[x + 1];
sumB[position] = ppData[x + 2];
if(i != 0)
{
sumR[position] += sumR[position - ppCanvasWidth];
sumG[position] += sumG[position - ppCanvasWidth];
sumB[position] += sumB[position - ppCanvasWidth];
}
if(j != 0)
{
sumR[position] += sumR[position - 1];
sumG[position] += sumG[position - 1];
sumB[position] += sumB[position - 1];
}
if(i != 0 && j != 0)
{
sumR[position] -= sumR[position - ppCanvasWidth - 1];
sumG[position] -= sumG[position - ppCanvasWidth - 1];
sumB[position] -= sumB[position - ppCanvasWidth - 1];
}
}
}

sumR sumG sumB分别存着三个通道内的预处理的值,radius表示模糊半径

具体计算模糊的代码:

     function ppBlur()
{
var area = (radius + radius + 1) * (radius + radius + 1);
for(var i = 0; i < ppCanvasHeight; i++)
{
for(var j = 0; j < ppCanvasWidth; j++)
{
var position = i * ppCanvasWidth + j;
var x = (position) * 4;
var tt = (i + radius) * ppCanvasWidth + j + radius;
var tt2 = (i - radius - 1) * ppCanvasWidth + j + radius;
var tt3 = (i + radius) * ppCanvasWidth + j - radius - 1;
var tt4 = (i - radius - 1) * ppCanvasWidth + j - radius - 1;
ppTemp[x] = (sumR[tt] - sumR[tt2] - sumR[tt3] + sumR[tt4]) / area;
ppTemp[x + 1] = (sumG[tt] - sumG[tt2] - sumG[tt3] + sumG[tt4]) / area;
ppTemp[x + 2] = (sumB[tt] - sumB[tt2] - sumB[tt3] + sumB[tt4]) / area;
}
}
ppData = ppTemp;
context.putImageData(ppImgData, 0, 0);
}
sumR[tt] - sumR[tt2] - sumR[tt3] + sumR[tt4]就是容斥出该正方形内R通道的和,再除以该区域内像素的总数即是平均值

总结:边界处理不好,在图片的边缘会明显变暗,主要是在边界处area的发生了变化

[canvas入坑2]模糊效果的更多相关文章

  1. [canvas入坑0] Jquery + HTML5 做最简易的画板

    查看效果请到 http://philippica.github.io/  点击paint 嗯,心血来潮想做个东西的一部分 html部分不用多说了,重点就是一个canvas <!DOCTYPE h ...

  2. [canvas入坑3] 类似ps中魔术棒或者画图中油漆桶的功能

    查看效果请到 http://philippica.github.io/  点击fill 这功能其实实现很low,最早高一看黑书的时候看到了floodfill算法感觉好神奇,转念一想这不就是bfs么!! ...

  3. [canvas入坑1]canvas 画布拖拽效果

    查看效果请到 http://philippica.github.io/  点击drag 和上一篇画图很像,所以有些部分做了省略 当鼠标按下时保存当前画布上的内容到ppImgData中,并且记录下初始点 ...

  4. web前端入坑第二篇:web前端到底怎么学?干货资料! 【转】

    http://blog.csdn.net/xllily_11/article/details/52145172 版权声明:本文为博主[小北]原创文章,如要转载请评论回复.个人前端公众号:前端你别闹,J ...

  5. RoboGuice 3.0 (一)入坑篇

    RoboGuice是什么? 一个Android上的依赖注入框架. 依赖注入是什么? 从字面理解,这个框架做了两件事情,第一是去除依赖,第二是注入依赖.简单理解就是,将对象的初始化委托给一个容器控制器, ...

  6. [SSIS] 在脚本里面使用数据库连接字符串进行查询等处理, 入坑

    入坑.!!!!! SSIS 中dts包 设置的  ADO.Net连接, 在传入脚本的时候, 我要使用 数据库连接,进行数据的删除操作. 于是我使用了 了如下的 代码 使用的是windows 身份验证, ...

  7. webpack入坑之旅(六)配合vue-router实现SPA

    这是一系列文章,此系列所有的练习都存在了我的github仓库中vue-webpack,在本人有了新的理解与认识之后,会对文章有不定时的更正与更新.下面是目前完成的列表: webpack入坑之旅(一)不 ...

  8. webpack入坑之旅(五)加载vue单文件组件

    这是一系列文章,此系列所有的练习都存在了我的github仓库中vue-webpack,在本人有了新的理解与认识之后,会对文章有不定时的更正与更新.下面是目前完成的列表: webpack入坑之旅(一)不 ...

  9. webpack入坑之旅(四)扬帆起航

    这是一系列文章,此系列所有的练习都存在了我的github仓库中vue-webpack,在本人有了新的理解与认识之后,会对文章有不定时的更正与更新.下面是目前完成的列表: webpack入坑之旅(一)不 ...

随机推荐

  1. 深入理解计算机系统_3e 第十一章家庭作业 CS:APP3e chapter 11 homework

    注:tiny.c csapp.c csapp.h等示例代码均可在Code Examples获取 11.6 A. 书上写的示例代码已经完成了大部分工作:doit函数中的printf("%s&q ...

  2. 深入理解计算机系统_3e 第十章家庭作业 CS:APP3e chapter 10 homework

    10.6 1.若成功打开"foo.txt": -->1.1若成功打开"baz.txt": 输出"4\n" -->1.2若未能成功 ...

  3. 【Python】bytes和hex字符串之间的相互转换。

    反复在几个环境上折腾码流的拼装解析和可读化打印,总是遇到hex字符串和bytes之间的转换,记录在这里吧. 1. 在Python2.7.x上(更老的环境真心折腾不起),hex字符串和bytes之间的转 ...

  4. 一些常用的集合工具的代码块(缓慢更新XD,更新了多属性过滤:) )

    更新记录 虽然经常放鸽子,但是还是要记录一下更新 2017.8.30 更新了listToMap的方法,现在可以指定多个属性进行分组了,例如你要指定一个学生集合,按照名字和年龄相同的放在一组,现在只要调 ...

  5. linux 命令学习(持续完善中...)

    linux 命令学习(持续完善中...) 主要是记录一些开发过程中用到的linux命令,慢慢补充 一.用户 1.添加用户: useradd 用户名 2.设置密码:passwd 用户名 ,然后按照提示输 ...

  6. 宏基笔记本升级bios(2012-12-28-bd 写的日志迁移

    首先到宏基官网下载中心 去下载你需要的新版本的bios安装包如图: 我的是宏基4750g的win7旗舰版64位,这里一定要根据自己的电脑的型号和安装的系统来选择,你可以选择最新的版本也可以选择老的版本 ...

  7. 虚拟机中配置SQL SERVER2008R2远程访问

    VM虚拟机中配置数据库访问 选择虚拟机设置--硬件--网络适配器,选择桥接模式:直接连接物理网络 不可选用主机模式(与主机共享专用网络) 数据库远程配置,转自:http://jingyan.baidu ...

  8. Disharmony Trees HDU - 3015

    Disharmony Trees HDU - 3015 One day Sophia finds a very big square. There are n trees in the square. ...

  9. hihocoder 1097 最小生成树一·Prim算法

    #1097 : 最小生成树一·Prim算法 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 最近,小Hi很喜欢玩的一款游戏模拟城市开放出了新Mod,在这个Mod中,玩家可 ...

  10. JAVA运行环境配置

    win10下,右击我的电脑-->高级系统设置-->高级-->环境变量-->系统变量 1新建 变量名   JAVA_HOME 变量值   C:\Program Files\Jav ...