查看效果请到 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. 在ListBox控件间交换数据

    实现效果: 知识运用: ListBox控件的SelectedItem属性 //获取或设置ListBox控件中当前选定的数据项 public Object SelectedItem{ get;set; ...

  2. react 信用卡格式检验

    前言: 技术栈主要基于react + ant-design 描述: 填写信用卡卡号时,会自动四位空格,并格式校验判断卡种  ,这里我们业务只涉及到四种卡. 代码解析 // ant 组件自引,这里我只讲 ...

  3. innobackup 参数

    innobackupex [--compress] [--compress-threads=NUMBER-OF-THREADS] [--compress-chunk-size=CHUNK-SIZE] ...

  4. oracle一些常用的数据类型

    字符数据类型 char数据类型 当需要固定长度时,使用char数据类型,此数据类型长度可以使1-2000字节.若是不指定大小默认占1字节,如果长度有空余时会以空格进行填充,如果大于设定长度 数据库则会 ...

  5. PHP计算两个字符的相似程度similar_text

    在网站开发中,我们会常常要计算两个字符的相似程度,那么PHP为我们提供了一个函数similar_text;  1,similar_text的用法 如果我想计算"ly89cn"和&q ...

  6. 06.VUE学习之非常实用的计算属性computed实例

    <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta http ...

  7. 一个手机号可以注册绑定5个百度网盘,永久2T

    效果: 一个手机号可以注册绑定5个百度网盘,得永久2T硬盘 手机号只能做为其中一个网盘的登陆账号,其它四个用绑定qq登陆(微信应该也可以). 条件: 2个手机号:A(用来绑定百度网盘),B(用来申请网 ...

  8. Farm Tour POJ - 2135 (最小费用流)

    When FJ's friends visit him on the farm, he likes to show them around. His farm comprises N (1 <= ...

  9. Hibernate中1+N问题以及解决方法

    1. Hibernate中的1+N问题描述 在多对一关系中,当我们需要查询多的一方对应的表的记录时,可以用一条sql语句就能完成操作.然而,在多的一方的实体类中的@ManyToOne标注的fetch的 ...

  10. MySQL基础9-主键约束、外键约束、等值连接查询、一对一和多对多关系

    1.主键约束和外键约束 外键约束 * 外键必须是另一表的主键的值(外键要引用主键!) * 外键可以重复 * 外键可以为空 * 一张表中可以有多个外键! 概念模型在数据库中成为表 数据库表中的多对一关系 ...