1、灰度滤镜

对于灰度滤镜的实现一般有三种算法

1) 最大值法:即新的颜色值R=G=B=Max(R,G,B),通过这种方法处理后的图片看起来亮度值偏高。

2) 平均值法:即新的颜色值R=G=B=(R+G+B)/3,这种方法处理的效果比较柔和

3) 加权平均值法:即新的颜色值R=G=B=(R*Wr+G*Wg+B*Wb),一般由于人眼对不同颜色的敏感度不一样,所以三种颜色值的权重不一样,一般来说绿色最高,红色其次,蓝色最低,最合理的取值分别为Wr=30%,Wg=59%,Wb=11%

在这里我们使用加权平均值法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
function greyEffect(canvasId){
    var canvas = document.getElementById(canvasId),
        ctx = canvas.getContext("2d"),
        imageData = ctx.getImageData(0,0,canvas.width,canvas.height),
        pixelData = imageData.data;
    for(var i=0;i<canvas.width*canvas.height;i++){
        var r = pixelData[i*4+0],
            g = pixelData[i*4+1],
            b = pixelData[i*4+2];
        var grey = 0.3 * r + 0.59 * g + 0.11 * b;
        pixelData[i*4+0] = grey;
        pixelData[i*4+1] = grey;
        pixelData[i*4+2] = grey;
    }
    return imageData;
}

2、黑白滤镜

算法原理:求RGB平均值Avg=(R+G+B)/3,如果Avg>=100,则新的颜色值为R=G=B=255;如果Avg<100,则新的颜色值为R=G=B=0;255就是白色,0就是黑色;至于为什么用100作比较,这是一个经验值吧,设置为128也可以,可以根据效果来调整。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
function blackEffect(canvasId){
    var canvas = document.getElementById(canvasId),
        ctx = canvas.getContext("2d"),
        imageData = ctx.getImageData(0,0,canvas.width,canvas.height),
        pixelData = imageData.data;
    for(var i=0;i<canvas.width*canvas.height;i++){ var r = pixelData[i*4+0], g = pixelData[i*4+1], b = pixelData[i*4+2]; var grey = (r+g+b)/3; if(grey>=100){
            v = 255;
        }else{
            v = 0;
        }
        pixelData[i*4+0] = v;
        pixelData[i*4+1] = v;
        pixelData[i*4+2] = v;
    }
    return imageData;
}

3、反相滤镜(底片效果)

算法原理:将当前像素点的RGB值分别与255之差后的值作为当前点的RGB值,即R=255–R;G=255–G;B=255–B

1
2
3
4
5
6
7
8
9
10
11
12
function reverseEffect(canvasId){
    var canvas = document.getElementById(canvasId),
        ctx = canvas.getContext("2d"),
        imageData = ctx.getImageData(0,0,canvas.width,canvas.height),
        pixelData = imageData.data;
    for(var i=0;i<canvas.width*canvas.height;i++){
        pixelData[i*4+0] = 255-pixelData[i*4+0];
        pixelData[i*4+1] = 255-pixelData[i*4+1];
        pixelData[i*4+2] = 255-pixelData[i*4+2];
    }
    return imageData;
}

4、模糊滤镜

算法原理:将当前像素的周边像素的RGB值各自的平均值作为新的RGB值。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
function blurEffect(size){
    var canvas = document.getElementById(canvasId),
        ctx = canvas.getContext("2d"),
        imageData = ctx.getImageData(0,0,canvas.width,canvas.height),pixelData = imageData.data,
        tmpimageData = ctx.getImageData(0,0,canvas.width,canvas.height),
        tmppixelData = imageData.data;
    size = size ? size : 1;
    var count = Math.pow((size*2+1),2)-1;
    for(var i=0;i<canvas.height;i++){
        for(var j=0;j<canvas.width;j++){
            var totalr = 0,totalg = 0,totalb = 0;
            for(var dx=i-size;dx<=i+size;dx++){
                for(var dy=j-size;dy<=j+size;dy++){
                    var p = dx * canvas.width + dy;
                    if(dx===i && dy===j) continue;
                    tmppixelData[p*4+0] && (totalr += tmppixelData[p*4+0]);
                    tmppixelData[p*4+1] && (totalg += tmppixelData[p*4+1]);
                    tmppixelData[p*4+2] && (totalb += tmppixelData[p*4+2]);
                }
            }
            var p = i * canvas.width + j;
            pixelData[p*4+0] = totalr/count;
            pixelData[p*4+1] = totalg/count;
            pixelData[p*4+2] = totalb/count;
        }
    }
    return imageData;
}

5、马赛克滤镜

算法原理:其实就是将图像分成大小一致的图像块,每一个图像块都是一个正方形,并且在这个正方形中所有像素值都相等。我们可以将这个正方形看作是一个模板窗口,模板中对应的所有图像像素值都等于该模板的左上角第一个像素的像素值,这样的效果就是马赛克效果,而正方形模板的大小则决定了马赛克块的大小,即图像马赛克化的程度。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
function gosike(size){
    var canvas = document.getElementById(canvasId),
        ctx = canvas.getContext("2d"),
        imageData = ctx.getImageData(0,0,canvas.width,canvas.height),pixelData = imageData.data,
        tmpimageData = ctx.getImageData(0,0,canvas.width,canvas.height),
        tmppixelData = imageData.data;
    size = size ? size : 16;
    var totalNum = Math.pow(size,2);
    var count = Math.pow((size*2+1),2);
    for(var i=0;i<canvas.height;i+=size){
        for(var j=0;j<canvas.width;j+=size){
            var totalr = 0,totalg = 0,totalb = 0;
            for(var dx=0;dx<=size;dx++){
                for(var dy=0;dy<=size;dy++){
                    var x = i + dx;
                    var y = j + dy;
                    var p = x * canvas.width + y;
                    totalr += tmppixelData[p*4+0];
                    totalg += tmppixelData[p*4+1];
                    totalb += tmppixelData[p*4+2];
                }
            }
            var p = i * canvas.width + j;
            var avgr = totalr/count;
            var avgg = totalg/count;
            var avgb = totalb/count;
            for(var dx=0;dx<=size;dx++){
                for(var dy=0;dy<=size;dy++){
                    var x = i + dx;
                    var y = j + dy;
                    var p = x * canvas.width + y;
                    pixelData[p*4+0] = avgr;
                    pixelData[p*4+1] = avgg;
                    pixelData[p*4+2] = avgb;
                }
            }
        }
    }
    return imageData;
}

6、浮雕滤镜

算法原理:用当前点的RGB值减去相邻点的RGB值并加上128作为新的RGB值。由于图片中相邻点的颜色值是比较接近的,因此这样的算法处理之后,只有颜色的边沿区域,也就是相邻颜色差异较大的部分的结果才会比较明显,而其他平滑区域则值都接近128左右,也就是灰色,这样就具有了浮雕效果。在实际的效果中,这样处理后,有些区域可能还是会有一些"彩色"的点或者条状痕迹,所以最好再对新的RGB值做一个灰度处理。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
function outset(size){
    var canvas = document.getElementById(canvasId),
        ctx = canvas.getContext("2d"),
        imageData = ctx.getImageData(0,0,canvas.width,canvas.height),
        pixelData = imageData.data,
        precolor = {};
    for(var i=0;i<canvas.width*canvas.height;i++){
        if(i==0){
            precolor = {
                r : pixelData[i*4+0],
                g : pixelData[i*4+1],
                b : pixelData[i*4+2]
            }
        }else{
            var r = pixelData[i*4+0] - precolor.r + 128;
            var g = pixelData[i*4+1] - precolor.g + 128;
            var b = pixelData[i*4+2] - precolor.b + 128;
            precolor = {
                r : pixelData[i*4+0],
                g : pixelData[i*4+1],
                b : pixelData[i*4+2]
            }
            pixelData[i*4+0] = r;
            pixelData[i*4+1] = g;
            pixelData[i*4+2] = b;
        }
        var r = pixelData[i*4+0],
            g = pixelData[i*4+1],
            b = pixelData[i*4+2];
        var grey = 0.3 * r + 0.59 * g + 0.11 * b;
        pixelData[i*4+0] = grey;
        pixelData[i*4+1] = grey;
        pixelData[i*4+2] = grey;
    }
    return imageData;
}

7、去色滤镜

算法原理:将当前像素的RGB值得最大值和最小值求平均值并作为新的RGB值。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
function removeColor(){
    var canvas = document.getElementById(canvasId),
        ctx = canvas.getContext("2d"),
        imageData = ctx.getImageData(0,0,canvas.width,canvas.height),
        pixelData = imageData.data;
    for(var i=0;i<canvas.width*canvas.height;i++){
        var r = pixelData[i*4+0],
            g = pixelData[i*4+1],
            b = pixelData[i*4+2];
        var c = Math.floor((Math.min(r,g,b) + Math.max(r,g,b))/2);
        pixelData[i*4+0] = c;
        pixelData[i*4+1] = c;
        pixelData[i*4+2] = c;
    }
    return imageData;
}

用Canvas实现一些简单的图片滤镜的更多相关文章

  1. Canvas 知识体系简单总结

    Canvas 知识体系简单总结 标签(空格分隔): HTML5 Canvas 本文原创,如需转载,请注明出处 前言 知识点零零散散,一个上午整理了一下,内容不多,方便记忆. 本文不是教程,如需教程移步 ...

  2. PHP《将画布(canvas)图像保存成本地图片的方法》

    用PHP将网页上的Canvas图像保存到服务器上的方法 2014年6月27日 歪脖骇客 发表回复 8 在几年前HTML5还没有流行的时候,我们的项目经理曾经向我提出这样一个需求:让项目评审专家们在评审 ...

  3. Expression Blend4经验分享:制作一个简单的图片按钮样式

    这次分享如何做一个简单的图片按钮经验 在我的个人Silverlight网页上,有个Iphone手机的效果,其中用到大量的图片按钮 http://raimon.6.gwidc.com/Iphone/de ...

  4. 将HTML5 Canvas的内容保存为图片借助toDataURL实现

    将HTML5 Canvas的内容保存为图片主要思想是借助Canvas自己的API - toDataURL()来实现,具体实现如下,感兴趣的朋友可以参考下哈,希望对你有所帮助 <html> ...

  5. jquery简单的图片切换效果,支持pc端、移动端的banner图片切换开发

    详细内容请点击 无意中看见了两年前写的一个图片切换,那会儿刚刚学习网页制作,可以说是我的第一个处女座的jquery图片切换效果.无聊之余对它的宽度稍稍做了一下修改,变成了支持pc端.手机端全屏的ban ...

  6. Objective-C ,ios,iphone开发基础:快速实现一个简单的图片查看器

    新建一个single view 工程: 关闭ARC , 在.xib视图文件上拖放一个UIImageView  两个UIButton ,一个UISlider ,布局如图. 并为他们连线, UIImage ...

  7. 一般处理程序生成简单的图片验证码并通过html验证用户输入的验证码是否正确

    一般处理程序生成简单的图片验证码并通过html验证用户输入的验证码是否正确       最近没事研究了下验证码的的动态生成及通过cookie实现HTML页面对用户输入的验证码的校验,简要如下: 1.写 ...

  8. 简单实现图片间的切换动画 主要用到ViewPager

    简单实现图片间的切换动画 主要用到ViewPagerViewPager是android扩展包v4包中的类,这个类可以让用户左右切换当前的view.ViewPager类需要一个PagerAdapter适 ...

  9. html5 canvas 实现一个简单的叮当猫头部

    原文:html5 canvas 实现一个简单的叮当猫头部 html5的canvas是很强大的,今天也是温习了一下之前的基础知识,然后学着做了一个简单的小案例.虽然在这一块几乎空白,但还是乐于尝试... ...

随机推荐

  1. 设计模式のInterpreter Patern(解释器模式)----行为模式

    一.问题产生背景 有一句话“小明和小龙是好朋友”,我想分析其中谁是人,我想分析他们的关系等多种需求,那么我们应该如何处理,如果为每一个关系都进行判断?显然不合适,我们可以将二者的关系进行抽象处理,然后 ...

  2. 16.ajax_case03

    # 抓取非小号的图表接口 # https://www.feixiaohao.com/currencies/raiden-network-token/ import requests import js ...

  3. SQLite中的WAL机制详细介绍-与回滚日志原理

    一.什么是WAL? WAL的全称是Write Ahead Logging,它是很多数据库中用于实现原子事务的一种机制,SQLite在3.7.0版本引入了该特性. 二.WAL如何工作? 在引入WAL机制 ...

  4. C#释放资源文件dll或exe

    将程序包含的资源文件释放到硬盘上 1.VS2017-新建  winform(窗体应用)命名为 loader 2.在解决方案管理器中,展开项目loader 在 properties 下面,找到[Reso ...

  5. tensorflow中的Supervisor

    tf.train.Supervisor()可以帮我们简化一些事情,可以保存模型参数和Summary,它有以下的作用: 1)自动去checkpoint加载数据或初始化数据 ,因此我们就不需要手动初始化或 ...

  6. [CQOI2018]交错序列

    嘟嘟嘟 要是求交错序列的个数和就好了,那我一秒就能切. 换成这个,我就不会了. 我一直想枚举1的个数,然后算出在长度为\(n\)的序列里,有多少个合法的序列,然后又觉得这好像是什么插板法,但是每一个盒 ...

  7. Linux 文件系统管理

    Linux 文件系统管理 课程大纲  文件系统构成及命令  硬盘分区及管理  磁盘配额  备份与恢复   文件系统构成 /usr/bin ./bin:存放所有用户可以执行的命令 /usr/s ...

  8. 微信硬件平台(九) 自己的服务器从微信获取token并保存txt

    1安装crontab: yum install crontabs 说明: service crond start //启动服务 service crond stop //关闭服务 service cr ...

  9. C语言之建立线性表

    #include<stdio.h> #include<stdlib.h> #define MaxSize 60 #define ElemType int typedef str ...

  10. Java线程安全与锁优化

    线程安全的严谨定义: 当多个线程访问一个对象时,如果不用考虑这些线程在运行时环境下的调度和交题执行,也不需要进行额外的同步,或者调用方法进行其他任何操作,调用这个对象的行为都可以或者正确的结果,那么这 ...