查看效果请到 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. apache的安全增强配置(使用mod_chroot,mod_security)

    apache的安全增强配置(使用mod_chroot,mod_security) 作者:windydays      2010/8/17 LAMP环境的一般入侵,大致经过sql注入,上传webshel ...

  2. python_20_列表

    #1 names=["QiZhiguang","DaiYang","HuZhongtao","ZhangDong"] p ...

  3. CUDA实现数组倒序

    数组倒序,将在主机上初始化的数组传输到设备上,然后用CUDA并行倒序,此时在全局内存上操作,再将结果返回到主机并验证. #include <stdio.h> #include <as ...

  4. iOS 闭包传值 和 代理传值

    let vc = ViewController() let navc = UINavigationController(rootViewController: vc) window = UIWindo ...

  5. IDEA Tomcat 日志和输出中文乱码问题

    说明:该方法是在网上查找的其他方法均无效的情况下自己摸索出的设置.既然别人有效的设置在我这里无效,那么以下设置自然有可能无效.建议综合多个搜索结果进行尝试. 仅需要进行两处设置 1. 更改 IDEA ...

  6. Vue中结合clipboard实现复制功能

    首先现在Vue中引入clipboard npm install clipboard --save 在需要使用的组件中import 引入clipboard import Clipboard from ' ...

  7. LAMP 一键部署

    LAMP 一键部署 部署http #!/bin/bash ### global variables export lamp_repo=http://192.168.1.5/lamp/ export l ...

  8. IDEA整合Mybatis+Struts2+Spring (二)--整合框架

    二.搭建目录结构 我这里列出的是搭建完了之后所有的目录和文件,诸位先把目录文件建起来,然后我在给出文件内容 这里的目录建好之后还需要设置一下,让idea识别目录作用,选择File-Project St ...

  9. wampserver怎么设置外网可访问

    wampserver配置httpd.conf允许外网访问? 在电脑上开启wamp服务后,默认是禁止外部网络访问的,如果您想要同一局域网中的设备能够访问PC上的web项目,则需要对httpd.conf文 ...

  10. Python学习笔记:装饰器

    Python 装饰器的基本概念和应用 代码编写要遵循开放封闭原则,虽然在这个原则是用的面向对象开发,但是也适用于函数式编程,简单来说,它规定已经实现的功能代码不允许被修改,但可以被扩展,即: 封闭:已 ...