ActionScript3游戏中的图像编程(连载八十八)

总目录:http://blog.csdn.net/iloveas2014/article/details/38304477

4.5.2 矩阵卷积的ActionScript实现

下面我们就尝试着在ActionScript里实现它,哇,那岂不是要操作像素的吗?请放心,跟ColorMatrixFilter一样,ActionScript也帮我们实现了卷积的滤镜——ConvolutionFilter:

ConvolutionFilter(matrixX:Number = 0, matrixY:Number = 0, matrix:Array = null, divisor:Number = 1.0, bias:Number = 0.0, preserveAlpha:Boolean = true, clamp:Boolean = true, color:uint = 0, alpha:Number = 0.0)

其中,前3个参数与矩阵相对应,因为matrix是一个一维数组,如果直接传9个1,那它可以是个3*3矩阵,也可以是9*1或者1*9,为此我们需要3个参数,分别代表行数,列数及矩阵的具体数值。

而第4个参数divisor则对应上面所说的因子了,在绝对平均分配的那个矩阵里,divisor=9,而修正为按圆扩展的矩阵里,divisor=11。

divisor的值不一定要跟矩阵内元素的总和相等,当divisor小于矩阵元素之和,颜色和alpha的成分就会增多,色彩会变明亮,或者呈现淡入的状态,反之变暗,或透明度淡出,而对于相等的情况,通常情况下也会有缓慢的淡出,因为计算结果的小数部分会被丢弃掉。

考虑到divisor的可变性,Adobe没有把这个因子写死在flashPlayer的底层上,而供我们自行设置。

其它参数我将结合实例进行讲解。

本书制作的效果的都尽可能地不使用现成的素材(微软雅黑字体除外),所以此处我们依然用一个TextField进行测试。

新建一个ActionScript项目,名为ConvolutionFilterTest,代码如下:

package{
[SWF(width = "800", height = "600")]
 public class ConvolutionFilterTest extends Sprite{
  private var _main_txt:TextField;
  public function ConvolutionFilterTest(){
   init();
  }
  private function init():void{
   initMainTxt();
  }
  private function initMainTxt():void{
   _main_txt = new TextField();
   _main_txt.autoSize = TextFieldAutoSize.LEFT;
   _main_txt.selectable = false;
   _main_txt.defaultTextFormat = new TextFormat("Microsoft YaHei", 80, null, true);
   _main_txt.text = "Flash艺术编程";
   _main_txt.filters = [new ConvolutionFilter(3, 3, [1, 1, 1, 1, 1, 1, 1, 1, 1], 9)];
   addChild(_main_txt);
  }
 }
}

运行效果如图 4.49所示,没什么特别嘛,跟设置滤镜前的状态没啥两样。

图 4.49 测试卷积滤镜

也是可以理解的,毕竟只是个纯色文本,再怎么交换颜色都还是黑色,而且只跟周边的1像素进行卷积,效果不明显也在情理之中。

既然如此,我们就不妨把卷积矩阵做大一点,扩充它的影响范围。

从3*3扩展到5*5(之所以不考虑4*4,是因为4*4没办法对齐到中心),矩阵数组的长度从9飙升到25。如果再要测试7*7,这么一个个手动敲,工作量可不少,而且容易出错。所以,在不考虑运行效率的情况下,我更倾向于书写一个生成指定尺寸矩阵数组的方法:

private function getConFilter(matrixSize:int, bias:Number = 0, preserveAlpha:Boolean = true, clamp:Boolean = true, color:uint = 0, alpha:Number = 0):ConvolutionFilter{
var amount:int = matrixSize * matrixSize;
var arr:Array = [];
for(var i:int = 0; i < amount; i ++){
 arr[i] = 1;
}
return new ConvolutionFilter(matrixSize, matrixSize, arr, amount, bias, preserveAlpha, clamp, color, alpha);
}

有了这样的一个方法,我们就可以轻松创建任意尺寸的方阵(行数=列数的矩阵叫方阵)了,如果在乎运行效率,就可以运用我之前说的代码片断思想去生成不需要运行时计算的代码,让开发运行两不误。

接下来把滤镜设置一句修改为:

_main_txt.filters = [getConFilter(5)];

现在我们只需要调整getConFilter内的参数就可以随意设置滤镜的作用范围了(这当然还不包含小数的情况)。

但运行后发现也还没有任何效果,何故?

此时我们就应该静下心来好好分析了。首先分析RGB,它们的通道值全等于0,而透明色,它由于全透明,所以无法携带RGB通道,通道值也等于0,于是就无法交换了。所以整个文本里,只有alpha至少通道包含了0和1这两个值。那么,我们不妨看看该滤镜是否包含了与alpha通道相关的参数。

扫视一番之后,我们发现两个这样的参数:preserveAlpha和alpha,其中alpha很显然是一个不透明度值,它看起来与通道设置不太相关,那我们看看preserveAlpha,它意为是否要保留着alpha通道,使其不发生变化,默认为true,而我们只有alpha通道可以实施变换,因此需要把该参数设置成false。

设置以后,效果如图 4.50所示。可以看到,边缘部分变模糊了,如果不断调大滤镜,或者重复使用,结果将会像烟雾一样缓缓消散。

图 4.50 设置preserveAlpha为false

找到问题的症结所在以后,我们不妨把矩阵尺寸调整回3*3,便得到如图 4.51的效果,虽然整体字型没有发生太大的变化,但是我们看到边缘变模糊了,这对于设备文本来说非常有用,用了它,边缘的锯齿大部分可以被消除,当然了,此法在消除锯齿方面也不是万能,比如小字号字体,轮廓较复杂的文字等,这些我们在后续章节再深入讨论。

图 4.51 将矩阵尺寸设置为3*3

如果说之前没看到滤镜效果是RGB通道之间无差异所引起的,如果说全透明色的RGB值都等于0,那么我把文本改成别的颜色,色彩就应该能发生交换了。如图 4.52,我把文本颜色改为纯红,并且把滤镜的尺寸调为5*5,文本边缘被描上了一条暗红色的边线(为什么是暗红,这跟alpha=0时的RGB数值有关,请读者自己思考)。

图 4.52 设置文本颜色为纯红

下面把模糊调大一点,比如20再看看效果(图 4.53)。

图 4.53 设置矩阵尺寸为20*20

模糊出来的结果附带了很多渣渣,而且出现了很多纵横交错的线条……似乎就是方形矩阵的副作用了。所以我们不妨尝试一下那种根据距离进行色彩分配的矩阵。

不过在进入之前,我想先让大家观察一下,是不是有种很熟悉的感觉?是不是跟之前模拟出来的某种渣渣有那么一些相似之处?没错,Flash的简单滤镜也有这样的问题!那到底Flash滤镜里用到的模糊是不是也基于这种模式呢?我们不妨换成BlurFilter看看:

_main_txt.filters = [new BlurFilter(20, 20)];

效果如图 4.54所示,渣渣还是掉了一地,而且调渣程度比ConvolutionFilter还高,再者,方块的感觉也出来了,就是颜色深了一点。所以,我们不妨尝试通过修改某些参数让ConvolutionFilter的效果与这个BlurFilter达到比较相似的效果。

图 4.54 测试BlurFilter的效果

首先BlurFilter的掉渣程度比较严重,所以我们不妨把模糊值改到10。因为BlurFilter的模糊值指的是模糊半径,而ConvolutionFilter的20*20矩阵中,将当前点置于变换矩阵的中心后,它也只与周边的10像素范围内的矩形区域发生关系。

BlurFilter调整为10后,效果如图 4.55所示。此时掉渣程度及其轮廓都已经与20*20的卷积滤镜相当接近了,但颜色却比卷积滤镜深了好多。

图 4.55 将BlurFilter的模糊值设置为10

既然模糊已经定型,那么我们就只能在ConvolutionFilter的颜色上做调整了。因为我们知道这个是纯黑的图像,RGB不可能变大,所以颜色淡肯定是alpha降低的结果,因此,我们要让计算的结果值变大,让文本变得更不透明一些。

逐个设置矩阵元素的做法有点不太科学,所以我们通过调整divisor参数对色彩进行整体调整,看起来乘以0.5,让alpha刚好放大一倍可以得到不错的结果:

return new ConvolutionFilter(matrixSize, matrixSize, arr, amount * 0.5, bias, preserveAlpha, clamp, color, alpha);

得到如图 4.56的效果,跟BlurFilter已经没什么两样了。

图 4.56 设置divisor等于矩阵元素总和的一半

由此可见,简单滤镜在实现模糊的过程中,用的就是ConvolutionFilter的矩阵卷积算法。至于这里面的乘以0.5,笔者也不会过于武断,单凭这一次的实验结果就确定了下来,因此,在接下来的时间里,笔者还继续对多种模糊值(包括不等的blurX和blurY)进行试验,并查阅与模糊算法相关的资料,才最终得出乘以0.5的结论。

这种模糊矩阵在图形学上也有一个专有名词:均值滤波法,因为其本质就是取周围像素的平均值作为新值应用到当前像素上。

时间: 2024-11-09 07:35:00

ActionScript3游戏中的图像编程(连载八十八)的相关文章

ActionScript3游戏中的图像编程(二十)

1.4.2 灰度的计算方法 回过头来看RGB,站在科学的角度来解释,它们确实也有更明亮的理由,因为下面一排色彩反射出来的色光总量是上一排色的两倍. 为此,作者曾自作聪明地发明了一条"原创"的灰度公式: Gray=(r+g+b)/3 哈哈,用色光总量来表达颜色的灰度想必就比较准确了吧!沾沾自喜一番以后,我还试着用这条自创的定律来转换这张测试图片,上下色块的灰度果然拉开了,可是很不幸地,左右相邻,边界分明的色块依然粘连在一块(图 1.30). 图 1.30 笔者"自创"

ActionScript3游戏中的图像编程(连载二十八)

2.2.1 投影颜色与透明度的模拟 默认的投影滤镜看着比Photoshop的投影样式浑浊,究其原因,似乎是颜色太深所致.(图 2.11). 图 2.11 设置默认投影滤镜后的效果 下面回到Photoshop查看其默认的投影参数(图 2.12). 图 2.12 Photoshop默认投影样式的参数 茫茫人海,我还是第一眼发现了你--颜色样本块.同是黑色,RGB都等于0,怎么差别还这么大?看来是A通道--不透明度惹的祸.从图 2.12中,我们看到Photoshop里对阴影设置了75%的不透明度,那F

ActionScript3游戏中的图像编程(连载八)

1.2.2 初始效果及颜色属性的测试 按F11/Ctrl+F11测试,效果如图 1.2所示.如果上下两组小圆色彩上看起来有所差别,那就请您校对下,看是否在输入代码的过程中出现了笔误,同时注意检查您的显示器是否因为老化,视角等问题而导致同种颜色在不同的位置有不同的效果.因为现在的代码仅仅做了一次赋值,中途并没有对ColorTransform进行其它处理. 图 1.2 变换前的效果 下面就先从效果最明显的color开始测试. 设置一下_myColorTransform.color = 0xFFFF0

ActionScript3游戏中的图像编程(连载四十八)

总目录:http://blog.csdn.net/iloveas2014/article/details/38304477 3.1.4 简单滤镜中的渐变原理探讨 我们再简单的看一下滤镜里的渐变条. 为了尽可能地减少复杂的文字轮廓所造成的干扰,我再次使用方块进行试验. 我画了一个紫色的方块(啥颜色其实都无所谓了),然后添加渐变发光滤镜,把模糊和距离值都调大,以便看清楚渐变的轮廓,然后给渐变条随意地加上几种颜色(图 3.30) 图 3.30 模糊范围较大的渐变发光 可以看到,渐变条上的色彩从右往左地

[原创]ActionScript3游戏中的图像编程(连载二十八)

2.2.1 投影颜色与透明度的模拟 默认的投影滤镜看着比Photoshop的投影样式浑浊,究其原因,似乎是颜色太深所致.(图 2.11). 图 2.11 设置默认投影滤镜后的效果 下面回到Photoshop查看其默认的投影参数(图 2.12). 图 2.12 Photoshop默认投影样式的参数 茫茫人海,我还是第一眼发现了你——颜色样本块.同是黑色,RGB都等于0,怎么差别还这么大?看来是A通道——不透明度惹的祸.从图 2.12中,我们看到Photoshop里对阴影设置了75%的不透明度,那F

ActionScript3游戏中的图像编程(连载十八)

1.3.4 HSB与RGB互转公式的ActionScript实现 为了让HSB转RGB这个通用的功能在后续的项目里可以重用,我们先把这个转换公式做成一个工具类,并且放入到公共类库里.当然,这样的类,网上也有很多现成的可以直接拿过来用(个人推荐frocessing工具包).类里的算法看起来跟公式会有点出入,一方面我自己也是从网上东拼西凑弄回来的,另一方面我把S和L/B的取值范围从0~1改成了0~100. 1 package com.gemei.geom { 2 public class Conve

ActionScript3游戏中的图像编程(连载二十)

1.4.2 灰度的计算方法 回过头来看RGB,站在科学的角度来解释,它们确实也有更明亮的理由,因为下面一排色彩反射出来的色光总量是上一排色的两倍.      为此,作者曾自作聪明地发明了一条“原创”的灰度公式: Gray=(r+g+b)/3 哈哈,用色光总量来表达颜色的灰度想必就比较准确了吧!沾沾自喜一番以后,我还试着用这条自创的定律来转换这张测试图片,上下色块的灰度果然拉开了,可是很不幸地,左右相邻,边界分明的色块依然粘连在一块(图 1.30). 图 1.30 笔者“自创”的灰度转换 显然此法

ActionScript3游戏中的图像编程(连载二十一,第1章完)

1.4.3 用灰度/明度指导色彩搭配 试着只通过调整不等于0的通道,让上一排的色彩在灰度上保持一致,把三个颜色分别代入到心理学公式.得 Gray(red) = r * 0.299      Gray(green) = g * 0.587      Gray(blue) = b * 0.114 让它们灰度相等,则 r * 0.299 = g * 0.587 = b * 0.114 可见,b值一定最大,不妨让b取最大值255,求得r=97, g=50.把这两个值分别应用到红和绿两个色块上. 绿色不再

ActionScript3游戏中的图像编程(连载十九)

1.4 浅析亮度与灰度/明度的关系 进入正题之前,先来了解一下灰度/明度. 1.4.1 灰度/明度的概念及其与HSB亮度的异同 在很多场合,灰度与明度的概念完全等价. “灰度”最初来源于摄影领域,在彩色显像技术问世以前,拍摄出来的照片只有黑,白,灰三类颜色,在这种黑白照片里,只有白色.黑色以及灰色的点能完好无损地显示出来,其它颜色将根据其亮度呈现出不同深度的灰色.亮度越大灰色越浅,反之越深.把黑与白色之间分成若干级,称为“灰度等级”.能呈现的灰度等级愈多,画面的层次感就愈丰富. 所以,从彩色转黑

[原创]ActionScript3游戏中的图像编程(连载三十二)

2.2.5 投影距离的模拟 Photoshop投影样式面板的下一个属性是距离,它也存在于Flash的投影滤镜选项中.两者初始值一致,经笔者测试,两者在效果实现和数值意义方面基本一致.Flash不需要对默认参数进行更改. 下一项是扩展,乍一看,在Flash中并没有找到对应项.但仔细观察,在Photoshop投影样式的基础选项里,除了alpha以外,就只剩该属性用了百分比. [原创]ActionScript3游戏中的图像编程(连载三十二),布布扣,bubuko.com