BitmapData类详解及应用(二)
六、创建噪波和布林噪波(杂点函数)
噪波图像是由一些随机的像素所组成的图案,可以用setPixel()来创建,也可以用noise()来创建,noise()比setPixel()功能更强。Noise()创建随机杂乱的图案,就像电视没有信号时的图像,再加上一些滤镜效果,就可以创建很多意想不到的效果了。
noise(seed,low,high,channel,grayscale):void
seed:决定随机样式,可以是任意值,如果用同样的值,调用两次则产生的图案一样。
Low,high:表示每个通道的最小值(0)和最大值(255),值越大,图像越亮。
Channel:四种颜色的通道,也可以用“|”组合所有通道。
Grayscale:布尔值,如果为true则创建一个灰度图。
下面的代码创建一个噪波图像,并使用模糊滤镜,如下:
var bmd:BitmapData = new BitmapData(100,100,true,0xff000000);
bmd.noise(1000,0,255,1|2|4|8,true);//灰度图
bmd.applyFilter(bmd,bmd.rect,new Point(),new BlurFilter(30,1,3));
var bm:Bitmap = new Bitmap(bmd);
addChild(bm);
布林噪波perlinNoise()和noise()一样创建随机图案,如爆炸,水,烟雾,木材纹理,山脉,云彩等。
perlinNoise(baseX,baseY,numOctaves,randomSeed,stitch,fractalNoise,channelOptions=7,grayscale = false,offset:Array = null):void
baseX,baseY:决定图案的大小,不是图像的大小。增大或减小其值,图案会进行拉伸,但图像大小不变。
numOctaves:迭代次数,数值越大,创建的图像越细腻,数值越大,运行越慢。
randomSeed:随机种子数,跟noise()用法一样。
stitch: 如果该值为 true,则该方法将尝试平滑图像的转变边缘以创建无缝的纹理,用于作为位图填充进行平铺。
fractalNoise:为true时,图案光滑且模糊化。
grayscale:是否灰度图。
offset:偏移量,point对象数组。
下面的代码时offset演示示例,如下:
private function init():void
{
bitmap = new BitmapData(w, h, true, 0xffffffff);
image = new Bitmap(bitmap);
addChild(image);
addEventListener(Event.ENTER_FRAME, onEnterFrame);
}
private function onEnterFrame(event:Event):void
{
_xoffset++;
var pt:Point = new Point(_xoffset, 0);
bitmap.perlinNoise(10, 10, 1, 1000, false, true, 1, false, [pt, pt]);
}
七、使用阀值修改像素。
threshold()方法用6个比较操作符和指定值,与源位图的每个像素做比较。如果返回false,则目标位图相应的位置像素被设置为指定值;如果返回true,要么不改变,也可拷贝源位图的像素值。
threshold(sourceBitmapData:BitmapData, sourceRect:Rectangle, destPoint:Point, operation:String, threshold:uint, color:uint = 0, mask:uint = 0xFFFFFFFF, copySource:Boolean = false):uint
下面的代码检测给定像素的红色通道(由mask定义),是否小于0x00880000,如果是,则设置为透明,否则拷贝像素
var srcBitmap:BitmapData = new BitmapData(w, h, true, 0xffffffff);
srcBitmap.perlinNoise(100, 100, 2, 1000, false, true, 1, false, null);
var destBitmap:BitmapData = new BitmapData(w, h, true, 0xffffffff);
destBitmap.threshold(srcBitmap, srcBitmap.rect, new Point(), "<", 0x00880000, 0x00000000, 0x00ff0000, true);
image = new Bitmap(destBitmap);
addChild(image);
还可以将使用阀值后的位图添加滤镜效果,以达到多种效果。
八、对位图使用滤镜
对位图进行滤镜处理有无损和有损两种。
1. 有损处理---applyFilter()会计算源位图中每个像素,然后覆盖,这样就修改了原始图像的数据。
applyFilter(sourceBitmapData:BitmapData,sourceRect:Rectangle,destPoint:Point,filter:BitmapFilter):void
sourceBitmapData:要添加滤镜效果的位图。可以是另一个BitmapData对象,也可以是当前对象。
sourceRect:位图上应用滤镜的区域。
destPoint: 目标图像(当前 BitmapData 实例)中与源矩形的左上角对应的点。
filter:滤镜对象。
下面的代码是示例:
var srcBitmap:BitmapData = new BitmapData(w, h, false, 0x000000);
var image:Bitmap = new Bitmap(srcBitmap);
addChild(image);
srcBitmap.noise(1000, 0, 255, 1 | 2 | 4 | 8, false);
var _blurFilter:BlurFilter = new BlurFilter();
srcBitmap.applyFilter(srcBitmap, srcBitmap.rect, new Point(), _blurFilter);
2. 无损处理
①.使用两个位图,一个作为源位图(srcBitmap),一个作为目标位图(destBitmap),滤镜应用在源位图上,结果保存在目标位图上。代码示例如下:
var srcBitmap:BitmapData = new BitmapData(w,h,false,0x000000);
var destBitmap:BitmapData = new BitmapData(w,h,false,0x000000);
var _blurFilter:BlurFilter = new BlurFilter();
srcBitmap.noise(1000,0,255,1|2|4,false);
srcBitmap.applyFilter(destBitmap,srcBitmap.rect,new Point(),_blurFilter);
var image:Bitmap = new Bitmap(destBitmap);
addChild(image);
②.利用Bitmap类的filters属性来控制,以达到滤镜效果。
var srcBitmap:BitmapData = new BitmapData(w,h,false,0x000000);
var _blurFilter:BlurFilter = new BlurFilter();
srcBitmap.noise(1000,0,255,1|2|4,false);
var image:Bitmap = new Bitmap(srcBitmap);
image.filters = [_blurFilter];
addChild(image);
九、两幅位图之间的过渡转换
pixelDissolve()方法使用一个源位图和一个目标位图,每次调用时从源位图拷贝指定数量随机位置的像素到目标位图,要完成转换,须重复调用,因此可以放在ENTER_FRAME事件或者基于时间轴的函数里。
seed=pixelDissolve(sourceBitmapData:BitmapData,sourceRect:Rectangle,destPoint:Point,randomSeed:int = 0, numPixels:int = 0, fillColor:uint = 0):int
返回值可以作为下一次调用时的种子。
下面的代码演示从白色位图到黑色过渡,每次从从源位图拷贝1000个像素,如下:
private function init():void
{
srcBitmap = new BitmapData(w, h, false, 0xffffffff);
destBitmap = new BitmapData(w, h, false, 0xff000000);
image = new Bitmap(srcBitmap);
addChild(image);
seed = Math.random() * 10000;
addEventListener(Event.ENTER_FRAME, onEnterFrame);
}
private function onEnterFrame(e:Event):void
{
seed = srcBitmap.pixelDissolve(destBitmap, srcBitmap.rect, new Point(), seed, 1000);
pixelCount+=1000;
//判断是否拷贝完成,删除事件。
if (pixelCount>w*h)
{
removeEventListener(Event.ENTER_FRAME, onEnterFrame);
}
}
如果自身位图的颜色变换过渡,如本身从白色过渡到红色,则修改一句代码,如下:
seed = srcBitmap.pixelDissolve(srcBitmap, srcBitmap.rect, new Point(), seed, 1000,0xffff0000);
这种溶解效果,经常应用于两张照片之间的过渡转换,如果要加快速度可以调大numPixels的值,如下每次拷贝1%的总像素,那么需要100帧可以完成,代码如下:
private function onEnterFrame(e:Event):void
{
var numPixels:Number = w * h / 100;
seed=srcBitmap.pixelDissolve(srcBitmap,srcBitmap.rect,newPoint(),seed,numPixels,0xffff0000);
pixelCount+=numPixels;
if (pixelCount>w*h)
{
removeEventListener(Event.ENTER_FRAME, onEnterFrame);
}
}
十、滚动显示位图
scroll()方法将图像按一定量的 (x, y) 像素进行滚动。滚动区域之外的边缘区域保持不变。通过ENTER_FRAME事件或者时间轴函数调用会形成滚动动画。
scroll(x:int, y:int):void
下面是一个具体的示例,代码如下:
private function init():void{
srcBitmap = new BitmapData(w, h, false, 0xffffffff);
srcBitmap.perlinNoise(100, 100, 1, 10, false, true, 1 | 2 | 4, false, null);
image = new Bitmap(srcBitmap);
addChild(image);
addEventListener(Event.ENTER_FRAME, onEnterFrame);
}
private function onEnterFrame(e:Event):void{
srcBitmap.scroll( -5, 0);
}