本文原创,总结Flash一般的图像处理方法,主要介绍PixelBender。
1 各种Filter类
前6个小玩意,正好对应Flash CS滤镜面板的几个效果,使用比较简单,详细可以参考这个: http://blog.sina.com.cn/s/blog_3fbce8b10100o8oz.html 。
后边的颜色矩阵滤镜和着色器滤镜就强大很多。下边详细说颜色矩阵滤镜。
2 颜色矩阵滤镜ColorMatrixFilter
上边的几个滤镜都会在元件周围或者里边做一些额外的显示,如果要只修改图片本身的色彩,例如黑白化,还是需要ColorMatrixFilter出马了。
参考:
http://blog.csdn.net/flag_and_leg/article/details/6412945
http://blog.sina.com.cn/s/blog_49b35d540100aks4.html
ColorMatrixFilter就是对图像中每个点的颜色值做调整,包括alpha值。使用ColorMatrixFilter很简单,但如果设置好里边每一个数值就非常有考究。
例如上述的参考网站中,要把一个图片黑白化(灰度),非常简单几句:
//加载一张彩色图片
var image:Bitmap=new Bitmap();
image=Bitmap(loader.content);
//定义滤镜matrix,一个包含20个项的数组
var matrix:Array=[0.3086, 0.6094, 0.0820, 0, 0,
0.3086, 0.6094, 0.0820, 0, 0,
0.3086, 0.6094, 0.0820, 0, 0,
0, 0, 0, 1, 0];
//初始化一个ColorMatrixFilter对象(matrix作为参数)
var myfilter:ColorMatrixFilter=new ColorMatrixFilter(matrix);
//将滤镜应用于图片
image.filters=[myfilter];
可以在这里尝试一下自己手工调整矩阵每个数字:
http://d2fhka9tf2vaj2.cloudfront.net/tuts/070_effectsTester/Preview/EffectsTester.html
另外,也有人整理了一些比较常用的基础照片处理用到的ColorMatrixFilter代码(对比度、饱和度、亮度什么的):
用这个代码,分别试验亮度、对比度和反相:
至于为什么是这么做,也有人说了一点分析:
http://cjdyx815.blog.163.com/blog/static/187705056201172322035148/
但由于这些都很容易搜索到,所以,这里就不详细展开说了。
那么,使用ColorMatrixFilter除了上述这些基本的照片处理功能外,有没有办法做出现成一点,比较有实际意义的滤镜效果呢?
答案是当然可以。例如上边说的黑白化就是了。
黑白:
[0.3086, 0.6094, 0.0820, 0, 0,
0.3086, 0.6094, 0.0820, 0, 0,
0.3086, 0.6094, 0.0820, 0, 0,
0, 0, 0, 1, 0]
旧照片:(网上搜集回来的,具体为什么这么计算,太难考究)
[0.3930000066757202, 0.7689999938011169, 0.1889999955892563, 0, 0,
0.3490000069141388, 0.6859999895095825, 0.1679999977350235, 0, 0,
0.2720000147819519, 0.5339999794960022, 0.1309999972581863, 0, 0,
0, 0, 0, 1, 0]
3 更原始的操作getPixel
通过BitmapData的getPixel,我们可以获取到每个像素点的颜色值,然后可以分离出红绿蓝每个通道的颜色,反之,也可以通过红绿蓝分别的值得到合并后的RGB值。
方法:
private static function mergeRGB(red:uint, green:uint, blue:uint):uint
{
return red << 16 | green << 8 | blue;
}
private static function getRed(color:uint):uint
{
return (color >> 16) & 0xFF;
}
private static function getGreen(color:uint):uint
{
return (color >> 8) & 0xFF;
}
private static function getBlue(color:uint):uint
{
return color & 0xFF;
}
那么,分离有什么用呢?单纯分离出每个通道的色值,当然没什么用。。。但通过各种图像算法,把每个通道的色值做一定修改、叠加,然后用setPixel还原回去,得到新的bitmapData,就会有新的图像了。
但是,这个合并算法,当然相对比较复杂了。但我们还是可以google到一些零星的例子,例如接下来要展示的LOMO效果:
上边4个图,分别就是几步操作的结果,详细参考: http://bbs.9ria.com/thread-83906-1-1.html
4 高级高效的pixelbender
其实pixelbender,在我理解,是getPixel的高级版,按官方介绍说,getPixel,我们只能逐个逐个点去算,但pixelbender是独立的程序,可以一批去算。比较简洁的介绍: http://www.pixelbender.cn/?p=130
什么是一个pixel shader?简单来说,就是一个用来计算像素值的程序。这样说也好像太简单了吧,不过这就是pixel shader要做的基本任务。各种pixel shader都是由输入和复杂运算算法组成的,最后它只会告诉你:“这个像素应该是这个值。”
有很多原因说明为什么Pixel Bender是一项牛B项目、为什么人们都为它感到兴奋。第一,Pixel Bender可以应用于位图、填充以及其它可视对象,然后运行pixel shader作用在每一个像素。不是逐个逐个,而是一次过。没错,它是在同一时间计算一个区域内的所有像素值。它编译后得到优化并且运行在独立的进程,是 独立于Flash Player的。总而言之,相对于Flash里的图形处理,pixel shader的执行效率是非常快的。
简单几步就可以理解pixelbender了:
var
filter:ShaderFilter=new
ShaderFilter(shader);然后赋值给元件的filters属性。自动把该元件的作为第一个image4输入。
用于混合模式。http://www.pixelbender.cn/?p=73。
设置参数: shader.data.xres.value = [20]; 其中xres是pb代码中设置的参数,以数组形式赋值 效率对比
本次对比使用了一个利用三张模版图片混合实现的滤镜(照片秀滤镜——彩虹)作为测试:
getPixel逐个计算 | pixelBender | |
---|---|---|
大图(2592*1936) | 31秒 | 480毫秒 |
小图(402*402) | 1.2秒 | 120毫秒 |
可以看出,效率是天壤之别。。
5 更进一步的图像处理
到了上边说的getPixel和pixelbender层级之后,我们就会发现,越来越迷惑,为什么一些滤镜要各种相乘相加相减。有什么道理么?
如果需要明白这些,就需要从图像的基本知识开始了。例如RGB是什么,饱和度是什么等等。
但一般用到几个图像合并的话,就需要了解blend mode。也就是相乘相加什么的,赶紧点这里: http://en.wikipedia.org/wiki/Blend_modes
另外也可以跟摄影照片后期处理的曲线关联起来,理解一下。
比较常见的是:Multiply和Screen,分别让图片变暗和变亮