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);

              }

posted @ 2010-06-16 13:54  rob_2010  阅读(352)  评论(0编辑  收藏  举报