Canvas滤镜预研
最近小花对Q拍的滤镜效果很感兴趣,折腾了一下,其实用canvas也可以模拟这些效果。
先看个demo:
***体验配置:pc用chrome或safari打开或iPad/iPad2/iPhone4打开这里 。
纯web图形处理与native app图形处理的区别,这里就不阐述了。欢迎大家讨论。
以下为全文:
HTML5 的canvas相信大家早有听闻,不支持flash的IOS设备要对图形处理可以用它来实现。canvas API内容挺多的,以下只是抽取部分属性和方法来阐述,抛砖引玉一下。
本文的主要内容是: canvas的简单图形处理,其中包括编码读写、像素级处理以及简单用法。这些操作都是在客户端处理的。
***. 要进行图片处理,首先考虑的应该是编码的读写。
1. 来看一下canvas是怎样读取图片。
这里要留意了,有些同学开始玩canvas的时候死活读不进图片,原因在于:你得首先让图片加载进来,因为程序跑得比图片加载快。
这里有必要了解一下,canvas画布的概念,简单可以描述为: 用canvas.getContext(“2d”)方法来获取一个2d画布,画布有自身的方法。用这些方法就可以在画布上面乱涂拉!
其中drawImage是用来把图片“涂”进来的,它有3个函数原型
关于这三个方法,看了下面这个图就会明白:
其实看起来还是有点纠结,没关系,我们这里重点在于***句,因为本来就是想着图片处理,那把canvas的宽度设成图片的宽高,然后把图片读进来放在canvas画布ctx的左上角就OK拉。说白了,就是读取图片的时候就是: 做一个跟图片看起来一模一样的canvas。
这样,很简单就把图片读进来了!Amazing!
2. canvas怎样输出编码?
当你用画布的方法乱涂乱画之后,用以下方法可以很简单输出图片编码:
这方法是canvas对象的,不是画布的。type可以在image/png,image/jpeg,image/svg+xml等 MIME类型中选择。如果是image/jpeg,可以有第二个参数,如果第二个参数的值在0-1之间,则表示JPEG的质量等级,否则使用浏览器内置默认质量等级。
以下以” image/png”为例,可以输出一段这样的字符串:
这是一段灰常灰常长的字符串!他叫Data URI。
注意.假如开始用drawImage“涂”进来的图片的src地址是跨域的(例如,网页放在a.com而图片的地址是b.com/c.jpg),这样的话,这个toDataUrl方法会报错。
那怎么办呢?蛋定,其实在需要处理这种图片时,先把它放到自己服务器转成同域就好了(可线下一起研究转换方法)。
这样,很简单就把图片输出来了!Unbelievable!
#p#
第二. 什么是canvas的像素级处理呢?
大家可以先看抽离出来的demo:
1. 图像的像素点是怎么存储的?
在进行图像处理前,得先了解一下图像是怎么存储每一个像素点的数据的。
看个图先:
玩css3的同学知道一个新的颜色定义方式—rgba,这里说的跟这个很像。
简单的像素点存储其实把每个像素点用四个数字来存储,分别是R(红)、G(绿)、B(蓝)、A(不透明度),然后这里的A值跟不透明度存在一个关系,60%=153/255,即不透明度=A值/255。
通过改变每个像素点的这四个维度,我们可以达到改变纯度,透明度,色相,亮度等所有效果,这是滤镜的基础原理,玩ps的盆友也许更熟悉这块。
2. Canvas怎么读写所有像素点数据?
a) 读取
画布的方法:getImageData可以获取指定范围内的像素点数据。参数x、y为起始位置,w、h为范围宽高。
该方法将返回形如以下的对象:
上图对应的是存储两个像素点数据的对象,对象中含有一个叫data的数组,其每四个键值对,存储一个像素点的数据,像素点从左到右排列。
b) 写入
画布的方法:putImageData可以把指定像素点数据对象(getImageData返回的对象),填充到指定位置,x、y为开始填充点。
第三. 用法?
了解上述原理和方法之后,只要遍历取出的像素点对象,再按指定的算法来改变每个像素点的数据,再把对象重绘到画布。
然后canvas对象来输出编码(***点),就能达到滤镜效果了。
效果的好坏主要取决于算法的好坏。
需要提醒的是,canvas的像素级处理比较耗费资源,但是对于宽高不是太大的图片,速度还是可以接受的。
这里顺带介绍一下QST库里头关于这个滤镜效果插件的简单使用:
其中preloaded为预载效果数量(由于对于某个图片,效果被渲染后会自动缓存在js对象里头,而执行渲染时需要时间,所以需要预载部分效果)。其他更详细参数,有兴趣的同学可线下交流。