卷积滤镜

Flash Player 9 和更高版本,Adobe AIR 1.0 和更高版本

ConvolutionFilter 类可用于对 BitmapData 对象或显示对象应用广泛的图像变形,如模糊、边缘检测、锐化、浮雕和斜角。

从概念上来说,卷积滤镜会逐一处理源图像中的每个像素,并使用像素和它周围的像素的值来确定该像素的最终颜色。指定为数值数组的矩阵可以指示每个特定邻近像素的值对最终结果值具有何种程度的影响。

最常用的矩阵类型是 3 x 3 矩阵。此矩阵包括九个值:

N    N    N 
N    P    N 
N    N    N

对特定像素应用卷积滤镜时,会检查该像素本身的颜色值(本示例中的“P”)以及周围像素的值(本示例中的“N”)。而通过设置矩阵中的值,可以指定特定像素在影响生成的图像方面所具有的优先级。

例如,使用卷积滤镜时应用的以下矩阵,会保持图像原样:

0    0    0 
0    1    0 
0    0    0

图像保持不变的原因是,在决定最终像素颜色时,原始像素的值相对强度为 1,而周围像素的值相对强度为 0(意味着它们的颜色不影响最终图像)。

同样,下面的这个矩阵会使图像的像素向左移动一个像素:

0    0    0 
0    0    1 
0    0    0

请注意,在本例中,像素本身不影响最终图像上显示在该位置的像素的最终值,而只使用右侧的像素值来确定像素的结果值。

在 ActionScript 中,您可以通过组合一个包含值的 Array 实例和两个指定矩阵中行数和列数的属性来创建矩阵。以下示例加载一个图像,完成加载该图像后,使用前面列表中的矩阵对该图像应用卷积滤镜:

// Load an image onto the Stage. 
var loader:Loader = new Loader(); 
var url:URLRequest = new URLRequest("http://www.helpexamples.com/flash/images/image1.jpg"); 
loader.load(url); 
this.addChild(loader); 
 
function applyFilter(event:MouseEvent):void 
{ 
    // Create the convolution matrix. 
    var matrix:Array = [0, 0, 0, 
                                     0, 0, 1, 
                                     0, 0, 0]; 
     
    var convolution:ConvolutionFilter = new ConvolutionFilter(); 
    convolution.matrixX = 3; 
    convolution.matrixY = 3; 
    convolution.matrix = matrix; 
    convolution.divisor = 1; 
     
    loader.filters = [convolution]; 
} 
 
loader.addEventListener(MouseEvent.CLICK, applyFilter);

此代码中没有明确显示使用除矩阵中 1 或 0 以外的值将会产生的效果。例如,同一矩阵中如果右侧位置的数字是 8 而不是 1,则它会执行同样的动作(向左移动像素)。此外,它还影响图像的颜色,使颜色加亮了 8 倍。这是因为最终像素颜色值的计算方法是:用原始像素颜色乘以矩阵值,将这些值加在一起,再除以滤镜的 divisor 属性的值。请注意,在示例代码中, divisor 属性设置为 1。通常,如果想让颜色的明亮度与原始图像保持基本相同,应让 divisor 等于矩阵值之和。因此,如果矩阵的值相加为 8,并且除数为 1,结果图像将比原始图像明亮约 8 倍。

虽然此矩阵的效果不是很明显,但可以使用其他矩阵值以产生各种不同效果。以下是几组标准矩阵值集合,用于使用 3 x 3 矩阵产生不同效果:

  • 基本模糊(除数 5):

         0 1 0 
         1 1 1 
         0 1 0
  • 锐化(除数 1):

         0, -1, 0 
        -1, 5, -1 
         0, -1, 0
  • 边缘检测(除数 1):

         0, -1, 0 
        -1, 4, -1 
         0, -1, 0
  • 浮雕效果(除数 1):

        -2, -1, 0 
        -1, 1, 1 
         0, 1, 2

    请注意,对于上述大部分效果,divisor 均为 1。这是因为负矩阵值加正矩阵值产生 1 (或边缘检测中的 0,但 divisor 属性的值不能为 0)。