简介
你使用过 flash的ColorMatrixFilter 和 ConvolutionFilter 吗?我在挖掘一些有趣的Flash功能,然后我发现了它们。用它们可以实现一些有趣的效果。
我写了一个EffectsTester 可以更方便的进行实验。
![attachimg.gif](http://bbs.9ria.com/images/default/attachimg.gif)
现在,如果你觉得很有趣,那么让我来告诉你有关它们的一切。
Color MatrixFilter
Color MatrixFilter是用来操纵先是对象的颜色的。
让我来解释ColorMatrixFilter是如何进行精确的计算的。图像中的每个像素都是一个红绿蓝混合体。这些原色能够混合成任何颜色。
![attachimg.gif](http://bbs.9ria.com/images/default/attachimg.gif)
红色的数值范围在0-255。绿色和蓝色也一样。所以在上面那张图你能够看出,纯黄是由255的红与255的绿构成。白色由255的红绿蓝构成。而黑色则是0的红绿蓝。
color matrixFilter关注源图中的每个像素,并且通过改变像素中红蓝绿的数值来改变图像。从而你能获得一个全新的图像。
来看看它怎么工作的
首先,我们关注一下三原色的值。
![attachimg.gif](http://bbs.9ria.com/images/default/attachimg.gif)
让我们依次标注a[0], a[1], a[2]的值。现在想象源图上的1个像素(左上角那个)。红色数值为srcR,绿色数值为srcG,还有蓝色的数值为srcB。
现在的问题是:最终图像上像素该有多少红,记为destR?Flash是这样计算的。
destR = ( a[0] * srcR ) + ( a[1] * srcG ) + ( a[2] * srcB );
在这里你能看到a[0]为1,a[1],a[2]都是0
destR = ( 1 * srcR ) + ( 0 * srcG ) + ( 0 * srcB );
//这意味着...
destR = srcR;
没有什么变化。但是如果我将a[0]变为0而a[1]变为1,那么
destR = ( 0 * srcR ) + ( 1 * srcG ) + ( 0 * srcB );
//这意味着...
destR = srcG;
目标像素上红与绿相等。此外,如果你将第二行改为“1 0 0”。然后目标像素上的绿将和红一样多。交换第一行和第二行的数值,你的橘色鱼就会变成绿色。
![attachimg.gif](http://bbs.9ria.com/images/default/attachimg.gif)
![attachimg.gif](http://bbs.9ria.com/images/default/attachimg.gif)
你可能想知道A列和Offset列。A表示透明度。A同RGB的效果相同,但由于这些例子 图片都不是透明的,所以不好看到效果。Offset列可以让你简单的增加或者减少像素上的红绿蓝:键入-255在R行的Offset列上,你就能看到图像上没有红色了。
实验
我知道如果只是阅读很难理解,所以,我们来看一些很酷的例子。这样会更有趣,但首先,我们先研究一下Flash中运用的数学公式:
- destR = ( a[0] * srcR ) + ( a[1] * srcG ) + ( a[2] * srcB ) + ( a[3] * srcA ) + a[4];
- destG = ( a[5] * srcR ) + ( a[6] * srcG ) + ( a[7] * srcB ) + ( a[8] * srcA ) + a[9];
- destB = ( a[10] * srcR ) + ( a[11] * srcG ) + ( a[12] * srcB ) + ( a[13] * srcA ) + a[14];
- destA = ( a[15] * srcR ) + ( a[16] * srcG ) + ( a[17] * srcB ) + ( a[18] * srcA ) + a[19];
看看“色表”示例图片:
![attachimg.gif](http://bbs.9ria.com/images/default/attachimg.gif)
现在,假设你要从图片中删除所有的红。只需要把所有R行上的值设为0就可以了。
![attachimg.gif](http://bbs.9ria.com/images/default/attachimg.gif)
这就意味着:
- destR = ( 0 * srcR ) + ( 0 * srcG ) + ( 0 * srcB ) + ( 0 * srcA ) + 0;
- //意味着:
- destR = 0 + 0 + 0 + 0 + 0;
- //所以:
- destR = 0;
那么就只要把G行设置为“1 1 0 0 0”
![attachimg.gif](http://bbs.9ria.com/images/default/attachimg.gif)
现在让我们把G行设置为“0 -1 0 0 50”,会看到一个很奇怪的效果。
![attachimg.gif](http://bbs.9ria.com/images/default/attachimg.gif)
刚才发生了什么?举个例子来说,如果在某些随即像素里,你的绿为30,它乘以-1 变迁后来偏移了50,所以结果将是(30*-1)+50=20;
因此,一个阙值就被创建了:对于每一个绿值大于50的像素将被完全关闭(变黑了).这是为什么呢?那么,假设像素的绿色通道的值为51:
- destG = ( 0 * srcR ) + ( -1 * srcG ) + ( 0 * srcB ) + ( 0 * srcA ) + 50;
- //记住 srcG = 51:
- destG = 0 + (-51) + 0 + 0 + 50;
- //所以:
- destG = - 51 + 50;
- //所以:
- destG = -1;
- //由于像素的绿不能为负值,所以设0:
- destG = 0;
![attachimg.gif](http://bbs.9ria.com/images/default/attachimg.gif)
所有绿大于50的像素都将关闭,并且绿低于50的三色通道都增加了。这样,你就能看到鱼图上只有非常少量的绿了。
x
![attachimg.gif](http://bbs.9ria.com/images/default/attachimg.gif)
在这里,只有那些绿低于50的像素。像素颜色越深,源图上的绿就越多。这些都是基本的原理。我知道初步接触的时候会觉得它很复杂,但是只要多加练习你就能掌握它。
灰度
好了,让我们搞一张灰度图来玩玩。依照下图设置你的矩阵:
![attachimg.gif](http://bbs.9ria.com/images/default/attachimg.gif)
你就会得到一个灰度图,奶丝~
![attachimg.gif](http://bbs.9ria.com/images/default/attachimg.gif)
反色
让我们来实现另外一个很流行的颜色状态:反色。
颠倒颜色,将每个像素中255的红改为0,反之亦然。其它两个颜色也这么操作。因此,我们需要Flash运行下面的代码:
- destR = 255 - srcR;
- destG = 255 - srcG;
- destB = 255 - srcB;
![attachimg.gif](http://bbs.9ria.com/images/default/attachimg.gif)
太好了,电鱼:
![attachimg.gif](http://bbs.9ria.com/images/default/attachimg.gif)
更多的效果
通过ColorMatrixFilter你可以实现更多的效果,只需要将颜色的值与偏移量设置为负数—或者相反。将0x3列与2x3列(透明度)设为-1,并且将4x3偏移量设为255。哇哦,我现在指导他们怎么弄终结者2的了。
老实说,我不知道我在做什么—跟踪一段时间后就会变得很难。
虽然可以从数学的角度来理解ColorMatrixFilter,但是你永远也无法确切的知道你设置的值会有什么效果。这就是我做EffectsTester的原因。因此,玩吧。创造你自己的金属绿,或者红色,或者无色。
真实世界的应用
当你有喜欢的效果的时候,你可以应用到任何的显示对象上(MovieClip,Sprite, Bitmap……),代码如下:
- //首先导入ColorMatrixFilter类
- import flash.filters.ColorMatrixFilter;
- //...接着:
- var filters:Array = new Array();
- //在实例化后,从 EffectsTester中复制和粘贴出数据:
- var cmf:ColorMatrixFilter = new ColorMatrixFilter(new Array(-1,0,0,0,255,0,-1,0,0,255,0,0,-1,0,255,0,0,0,1,0));
- //接下来两行就是把滤镜应用到你的显示对象上。:
- filters.push( cmf );
- myDisplayObject.filters = filters;
ConvolutionFilter来自 Adobe官方类参考
“在输入的图像中通过扭曲混合相邻的像素来创造新的图像。图像的各种效果可以通过扭曲,包括模糊,边缘检测,锐化,浮雕,斜角来实现。”
ConvolutionFilter会遍历显示对象所有像素。每个像素,都会使用矩阵的中心值。例如,在一个3x3的矩阵中。中心值就在(1,1)。然后乘以周围像素的值。然后为所有的点增加中心值。
要精确理解下面的Convolution matrix需要写一篇全新的文章,所以在这里我不会涵盖方方面面。如果你想深入了解它,可以看看这篇文章 http://www.adobe.com/devnet/flas ... sformations_05.html。
然而,通过简单的玩耍最终会创造你所能创造的特殊效果。这将是非常有趣的,所以让我们来看看我们能做什么。
实验
convolution filter使用一个矩,就像color matrix filter一样。同样,数值在-255到255之间。再次,正负相调能实现非常有趣的效果。
我想和大家分享一下我理解的工作原理。尝试给矩阵设置一些随即值。无论你怎么选择都能使图片变亮;如果你想图片保持正常的亮度,确保“除数”的值等于矩阵中所有值的总和。
现在如果你尝试一个低于0的随机数,那就要同时保持至少一个大于0的值。你就能看到产生什么效果了。它会影响你的边缘。
![attachimg.gif](http://bbs.9ria.com/images/default/attachimg.gif)
这里有一个奶丝的效果:想要像个士兵?尝试如下的参数:
![attachimg.gif](http://bbs.9ria.com/images/default/attachimg.gif)
现在,降低“除数”值为-1,像个夜行者。
如果你用 鼠标点点增加减少 按钮,你就能实现很多效果。不要忘记调整“除数”—这是至关重要的。放大你的矩阵,例如5x5,再继续尝试吧。
真实世界的应用
在你的代码中应用这个效果,使用filters对象,就像你在ColormatrixFilter中那样用。
- //导入 ConvolutionFilter:
- import flash.filters.ConvolutionFilter;
- //..接着:
- var filters:Array = new Array();
- //在所有的东西都实例化后.复制和粘贴EffectsTester上的值:
- var cf:ConvolutionFilter = new ConvolutionFilter(3,3,new Array(1,0,-10,-2,3,1,6,1,-1),0);
- //下面两行将滤镜应用到你的显示对象上:
- filters.push( cf );
- myDisplayObject.filters = filters;
- //导入类:
- import flash.filters.ColorMatrixFilter;
- import flash.filters.ConvolutionFilter;
- //... 接着:
- var filters:Array = new Array();
- //在所有东西实例化后,复制粘贴EffectsTester上的值:
- var cmf:ColorMatrixFilter = new ColorMatrixFilter(new Array(-1,0,0,0,255,0,-1,0,0,255,0,0,-1,0,255,0,0,0,1,0));
- var cf:ConvolutionFilter = new ConvolutionFilter(3,3,new Array(1,0,-10,-2,3,1,6,1,-1),0);
- //接下来的三行就是将滤镜数应用到显示对象上。
- filters.push( cf );
- filters.push( cmf );
- myDisplayObject.filters = filters;