As3.0中的位图(Bitmap/BitmapData)编程
1.位图使用(模糊)滤镜
//创建一个矩形区域的BitmapData var bmd:BitmapData = new BitmapData(80, 30, false, 0xefefef); //画个红色的矩形 var rect:Rectangle = new Rectangle(20, 10, 40, 10); bmd.fillRect(rect, 0xFF0000); //找到红色矩形的右上顶点 var pt:Point = new Point(rect.left, rect.top); //定义一个模糊滤镜 var filter:BlurFilter = new BlurFilter(8,8,1); //应用滤镜 bmd.applyFilter(bmd, rect, pt, filter); //创建一个位图对象,并加入到舞台 var bm:Bitmap = new Bitmap(bmd); bm.scaleX = bm.scaleY = 2.0; bm.x = stage.stageWidth/2 -bm.width/2; bm.y = stage.stageHeight/2 - bm.height/2 ; addChild(bm);
2.像素拷贝及赋值
var bmd1:BitmapData = new BitmapData(90, 60, false, 0x00000000); var bmd2:BitmapData = bmd1.clone();//拷贝 //"画"一条白色的线 for(var i:uint=10;i<=40;i++){ bmd1.setPixel32(i, i, 0xFFFFFFFF); } trace(bmd1.getPixel32(10, 10).toString(16)); // ffffffff trace(bmd2.getPixel32(10, 10).toString(16)); // ff000000 var bm1:Bitmap = new Bitmap(bmd1); this.addChild(bm1); bm1.x =bm1.y = 5; var bm2:Bitmap = new Bitmap(bmd2); bm2.x = 105; bm2.y =5; this.addChild(bm2);
3.颜色变换
var bmd:BitmapData = new BitmapData(80, 30, false, 0xFF0000); var cTransform:ColorTransform = new ColorTransform(); cTransform.alphaMultiplier = 0.8;//设置透明度因子为0.8 var rect:Rectangle = new Rectangle(0, 0, 40, 30);//定义左半边矩形区域 bmd.colorTransform(rect, cTransform);//对rect区域应用colorTransform var bm:Bitmap = new Bitmap(bmd); addChild(bm); bm.x = stage.stageWidth/2 - bm.width/2; bm.y = stage.stageHeight/2 - bm.height/2;
4.比较位图差异
var bmd1:BitmapData = new BitmapData(50, 50, true, 0xFFFFAA00); var bmd2:BitmapData = new BitmapData(50, 50, true, 0xCCFFAA00); var diffBmpData:BitmapData = BitmapData(bmd1.compare(bmd2)); var diffValue:String = diffBmpData.getPixel32(1, 1).toString(16); //解释:当二个位置尺寸大小相同,且仅alpha分量不同时,compare的值为 zzFFFFFF,其中zz为bmd1与bmd2的alpha分量差 trace (diffValue); // 33ffffff var bm1:Bitmap = new Bitmap(bmd1); addChild(bm1); bm1.x = bm1.y = 5; var bm2:Bitmap = new Bitmap(bmd2); addChild(bm2); bm2.x = 60; bm2.y = 5; var bmDiff = new Bitmap(diffBmpData); addChild(bmDiff); bmDiff.x = 115; bmDiff.y = 5;
var bmd1:BitmapData = new BitmapData(50, 50, true, 0xFF00FF99); var bmd2:BitmapData = new BitmapData(50, 50, true, 0x99AA3366); var diffBmpData:BitmapData = BitmapData(bmd1.compare(bmd2)); var diffValue:String = diffBmpData.getPixel32(1, 1).toString(16); //解释:当二个位置尺寸大小相同,但RGB分量不同时,compare的值为 FFxxyyzz,其中xx,yy,zz分别为bm1与bm2的RGB分量差,同时alpha分量差将被忽略 trace (diffValue); // ff56cc33 var bm1:Bitmap = new Bitmap(bmd1); addChild(bm1); bm1.x = bm1.y = 5; var bm2:Bitmap = new Bitmap(bmd2); addChild(bm2); bm2.x = 60; bm2.y = 5; var bmDiff = new Bitmap(diffBmpData); addChild(bmDiff); bmDiff.x = 115; bmDiff.y = 5;
5.拷贝颜色通道
var bmd:BitmapData = new BitmapData(stage.stageWidth, stage.stageHeight, false, 0x00FF0000); var rect:Rectangle = new Rectangle(0, 0, 20, 40); var pt:Point = new Point(10, 10); bmd.copyChannel(bmd, rect, pt, BitmapDataChannel.RED, BitmapDataChannel.BLUE);//将红色通道复制到以(10,10)为顶点,宽为20,高为40的矩形区域的蓝色通道中 trace(bmd.getPixel32(10,10).toString(16));//ffff00ff,即矩形区域的最终颜色值为ff ff 00 ff(纯红 叠加 纯蓝) var bm:Bitmap = new Bitmap(bmd); this.addChild(bm);
6.截取位图的某一部分(像素)
var bmd1:BitmapData = new BitmapData(40, 40, false, 0x000000FF); var bmd2:BitmapData = new BitmapData(80, 40, false, 0x0000CC44); var rect:Rectangle = new Rectangle(0, 0, 20, 20); var pt:Point = new Point(10, 10); bmd2.copyPixels(bmd1, rect, pt);//将bmd1中以pt为左上顶点的rect矩形像素复制到bmd2中 var bm1:Bitmap = new Bitmap(bmd1); this.addChild(bm1); var bm2:Bitmap = new Bitmap(bmd2); this.addChild(bm2); bm2.x = 50;
7.将文本转换为位图
import flash.display.Bitmap; import flash.display.BitmapData; import flash.text.TextField; var tf:TextField = new TextField(); tf.text = "bitmap text"; var myBitmapData:BitmapData = new BitmapData(80, 20); myBitmapData.draw(tf); var bmp:Bitmap = new Bitmap(myBitmapData); this.addChild(bmp); bmp.x = stage.stageWidth/2 - bmp.width/2; bmp.y = stage.stageHeight/2 - bmp.height/2;
8.仿PS中的颜色填充工具
//准备一个40*40绿色背景的BitmapData var myBitmapData:BitmapData = new BitmapData(40, 40, false, 0x0000FF00); //画二个有“交叉重叠”部分的“蓝色”矩形 var rect:Rectangle = new Rectangle(0, 0, 25, 25); myBitmapData.fillRect(rect, 0x000000FF); rect = new Rectangle(20, 20, 20, 20); myBitmapData.fillRect(rect, 0x000000FF); //从坐标(10,10)开始寻找与(10,10)坐标(像素点相同且连续的区域)填充红色 myBitmapData.floodFill(10, 10, 0x00FF0000); var bm:Bitmap = new Bitmap(myBitmapData); addChild(bm); bm.scaleX = bm.scaleY = 3.0; bm.x = stage.stageWidth/2 - bm.width/2; bm.y = stage.stageHeight/2 - bm.height/2;
9.颜色融合
import flash.display.Bitmap; import flash.display.BitmapData; import flash.geom.Rectangle; import flash.geom.Point; var bmd1:BitmapData = new BitmapData(100, 80, true, 0xFF00FF00); var bmd2:BitmapData = new BitmapData(100, 80, true, 0xFFFF0000); var rect:Rectangle = new Rectangle(0, 0, 40, 40); var pt:Point = new Point(20, 20); var mult:uint = 0x80; // 50% ,各通道值均为128,即50% bmd1.merge(bmd2, rect, pt, mult, mult, mult, mult); var bm1:Bitmap = new Bitmap(bmd1); addChild(bm1); var bm2:Bitmap = new Bitmap(bmd2); addChild(bm2); bm2.x = 110; //最终值 //new redDest = [(redSrc * redMultiplier) + (redDest * (256 - redMultiplier))] / 256; trace(bmd1.getPixel32(20,20).toString(16)); //ff7f7f00 //解释: //返回值中Red分量为 7f = 0x00 * 0x80 + 0xff*(0x100-0x80)/0x100
10.噪点图
var bmd1:BitmapData = new BitmapData(80, 80); var bmd2:BitmapData = new BitmapData(80, 80); var seed:int = int(Math.random() * int.MAX_VALUE); bmd1.noise(seed, 0, 0xFF, BitmapDataChannel.RED, false); bmd2.noise(seed, 0, 0xFF, BitmapDataChannel.RED, true); var bm1:Bitmap = new Bitmap(bmd1); this.addChild(bm1); bm1.x = 10; bm1.y = 10; var bm2:Bitmap = new Bitmap(bmd2); this.addChild(bm2); bm2.x = 100; bm2.y = 10; stage.addEventListener(Event.ENTER_FRAME,enterFrameHandler); function enterFrameHandler(e:Event):void{ seed = Math.floor(Math.random() * int.MAX_VALUE); bmd1.noise(seed, 0, 0xFF, BitmapDataChannel.RED, false); bmd2.noise(seed, 0, 0xFF, BitmapDataChannel.RED, true); bm1.bitmapData = bmd1; bm2.bitmapData = bmd2; }
11.另一种噪点图(有点类似卫星云图)
import flash.display.Bitmap; import flash.display.BitmapData; var bmd:BitmapData = new BitmapData(200, 200, false, 0x00CCCCCC); var seed:Number = Math.floor(Math.random() * 999999); var channels:uint = BitmapDataChannel.GREEN | BitmapDataChannel.BLUE; bmd.perlinNoise(100, 80, 6, seed, false, true, channels, false, null); var bm:Bitmap = new Bitmap(bmd); addChild(bm); bm.x = stage.stageWidth/2 - bm.width/2; bm.y = stage.stageHeight/2 - bm.height/2; stage.addEventListener(Event.ENTER_FRAME,enterFrameHandler); function enterFrameHandler(e:Event):void{ seed = Math.floor(Math.random() * 999999); bmd.perlinNoise(100, 80, 6, seed, false, true, channels, false, null); bm.bitmapData = bmd; }
12.像素融解
import flash.display.BitmapData; import flash.display.Bitmap; import flash.geom.Point; import flash.geom.Rectangle; import flash.utils.Timer; import flash.events.TimerEvent; var rndColor:int = Math.random() * 0xffffffff;//随机背景色 var fillColor:int = Math.random() * 0xffffffff;//随机填充色 var bmd:BitmapData = new BitmapData(100, 100, false, rndColor); var bitmap:Bitmap = new Bitmap(bmd); addChild(bitmap); bitmap.scaleX = bitmap.scaleY = 1.5; bitmap.x = stage.stageWidth/2 - bitmap.width/2; bitmap.y = stage.stageHeight/2 - bitmap.height/2; var tim:Timer = new Timer(20); tim.start(); tim.addEventListener(TimerEvent.TIMER, timerHandler); function timerHandler(event:TimerEvent):void { var randomNum:Number = Math.floor(Math.random() * int.MAX_VALUE); dissolve(randomNum); } function dissolve(randomNum:Number):void { var rect:Rectangle = bmd.rect; var pt:Point = new Point(0, 0); var numberOfPixels:uint = 100;//每次融解100个像素 bmd.pixelDissolve(bmd, rect, pt, randomNum, numberOfPixels, fillColor); var grayRegion:Rectangle = bmd.getColorBoundsRect(0xFFFFFFFF, rndColor, true); if(grayRegion.width == 0 && grayRegion.height == 0 ) { bmd.dispose(); rndColor = Math.random() * 0xffffffff; fillColor = Math.random() * 0xffffff; bmd = new BitmapData(100, 100, false, rndColor); bitmap.bitmapData = bmd; //tim.stop(); } }
13.查找满足条件的颜色并替换
import flash.display.Bitmap; import flash.display.BitmapData; import flash.display.BitmapDataChannel; import flash.geom.Point; import flash.geom.Rectangle; var bmd1:BitmapData = new BitmapData(200, 200, true, 0xFFCCCCCC); var seed:int = int(Math.random() * int.MAX_VALUE); var channels:uint = BitmapDataChannel.RED | BitmapDataChannel.BLUE; bmd1.perlinNoise(100, 80, 12, seed, false, true, channels, false, null); var bitmap1:Bitmap = new Bitmap(bmd1); addChild(bitmap1); var bmd2:BitmapData = new BitmapData(200, 200, true, 0xFFCCCCCC); var pt:Point = new Point(0, 0); var rect:Rectangle = new Rectangle(0, 0, 200, 200); var threshold:uint = 0x00800000;//50%的红色通道值 var color:uint = 0x80FF0000;//替换后的颜色 var maskColor:uint = 0x00FF0000;//因为只查找红色通道,所以遮罩仅为纯红色通道 bmd2.threshold(bmd1, rect, pt, ">", threshold, color, maskColor, true); var bitmap2:Bitmap = new Bitmap(bmd2); bitmap2.x = bitmap1.x + bitmap1.width + 10; addChild(bitmap2); addEventListener(Event.ENTER_FRAME,EnterFrameHandler); function EnterFrameHandler(e:Event):void{ seed = int(Math.random() * int.MAX_VALUE); bmd1.perlinNoise(100, 80, 12, seed, false, true, channels, false, null); bitmap1.bitmapData = bmd1; bmd2.threshold(bmd1, rect, pt, ">", threshold, color, maskColor, true); bitmap2.bitmapData = bmd2; }
14.综合应用1:模仿MetaBall(当然这种方法并不精确)
var ballNum:uint=5; var balls:Array = new Array(); var sW:Number=stage.stageWidth; var sH:Number=stage.stageHeight; var container:Sprite = new Sprite(); var bmd:BitmapData=new BitmapData(sW,sH,false,0x00000000); var bitmap:Bitmap; var i:uint=0; var rect:Rectangle=new Rectangle(0,0,sW,sH); var pt:Point=new Point(0,0); var filter:BlurFilter=new BlurFilter(15,15); function init() { for (i=0; i<ballNum; i++) { var b:Ball=new Ball(30+Math.random()*40,0xffffff); balls.push(b); b.x = (sW - b.width)*Math.random() + b.radius; b.y = (sH - b.width)*Math.random() + b.radius; b.vx=(Math.random()*2-1)*2; b.vy=(Math.random()*2-1)*2; container.addChild(b); } bmd.draw(container); bmd.applyFilter(bmd, rect, pt, filter); bitmap=new Bitmap(bmd); addChild(bitmap); addEventListener(Event.ENTER_FRAME,enterFrameHandler); } function enterFrameHandler(e:Event):void { for (i=0; i<ballNum; i++) { var b:Ball=balls[i]; b.x+=b.vx; b.y+=b.vy; var adjust:uint=5; if (b.x>=sW-b.radius-adjust) { b.x=sW-b.radius-adjust; b.vx*=-1; } else if (b.x<b.radius+adjust) { b.x=b.radius+adjust; b.vx*=-1; } if (b.y>=sH-b.radius-adjust) { b.y=sH-b.radius-adjust; b.vy*=-1; } else if (b.y<b.radius+adjust) { b.y=b.radius+adjust; b.vy*=-1; } } bmd.dispose(); bmd=new BitmapData(sW,sH,false,0x00000000); bmd.draw(container); bmd.applyFilter(bmd, rect, pt, filter); bitmap.bitmapData=bmd; } init();
15.综合应用2-粒子效果
package asbook { import flash.display.* import flash.geom.* public class particleSample extends Sprite { private var apoint : Point; private var aspeed : Number = 0; private var arote : Number = 0; private var cpoint : Point; private var rl : Number = 0; public function particleSample(cp:Point , lg:Number , art:Number , asp:Number):void {// 1s apoint = new Point(); cpoint = cp; rl = lg; arote = art; aspeed = asp; setapoint(); }// 1e public function pmove():Point {// 2s arote += aspeed; if(arote >= 360) arote -= 360; setapoint(); return apoint; }// 2e public function setapoint():void {// 3s var temp:Number = arote * Math.PI / 180; apoint.x = cpoint.x + rl * Math.cos(temp); apoint.y = cpoint.y + rl * Math.sin(temp); }// 3e }// class end }// package end
package asbook{ import flash.events.*; import flash.display.*; import flash.text.*; import flash.utils.*; public class FPSshow extends Sprite { private var FPStxt:TextField; private var FPScount:Number; private var FPStimer:int; private var fm:TextFormat; public function FPSshow() { fm = new TextFormat(); fm.size = 20; FPStxt = new TextField(); FPStxt.defaultTextFormat = fm; FPScount = 0; FPStxt.textColor = 0xFFFFFF; FPStxt.x = 10; FPStxt.y = 10; addEventListener(Event.ADDED , onadd); addEventListener(Event.REMOVED , onremove); } private function onadd(evt:Event) { stage.addEventListener(Event.ENTER_FRAME , showFPS); addChild(FPStxt); FPStimer = getTimer(); } private function onremove(evt:Event) { stage.removeEventListener(Event.ENTER_FRAME , showFPS); } private function showFPS(evt:Event ) { if ( getTimer() - 1000 > FPStimer ) { FPStimer = getTimer(); FPStxt.text = "FPS : "+FPScount; FPScount = 0; } else { FPScount++; } } }//end class }//end package
package asbook{ import asbook.particleSample; import asbook.FPSshow; import flash.filters.*; import flash.display.*; import flash.geom.*; import flash.events.*; [SWF(height="300",width="300",frameRate=100)] public class main extends MovieClip { private var gNum1:int=1500; private var gNum2:int=1500; private var gArr:Array=[]; private var ccPoint:Point; private var rrl:Number; private var length1:Number=50; private var length2:Number=200; private var length3:Number=300; private var bmp:Bitmap; private var bmd:BitmapData; private var bmdctf:ColorTransform=new ColorTransform(0.96,0.86,0); private var stgw:Number=stage.stageWidth; private var stgh:Number=stage.stageHeight; private var started:Boolean=false; private var bmped:Boolean=false; public function main() { ccPoint=new Point(stgw/2,stgh/2); initbmp(); initstart(); addEventListener(Event.ENTER_FRAME , run); addChild( new FPSshow() ); } private function initbmp():void { if (bmped) { return; } bmped=true; bmd=new BitmapData(stgw,stgh,false,0); bmp=new Bitmap(bmd); addChild(bmp); } private function initstart():void { if (started) { return; } started=true; for (var i:int = 1; i <= gNum1; i++) { rrl=Math.abs(Math.random()-Math.random()); var pp:particleSample = new particleSample(ccPoint , rrl * ( (length2 - length1) / 2 * 1.2 ) + length1 / 2 , Math.random() * 360 , Math.random() * 10 - 6 ); gArr.push(pp); } for (i = 1; i <= gNum2; i++) { rrl=Math.abs(Math.random()-Math.random()); var pp:particleSample = new particleSample(ccPoint , rrl * (length3 - length2) / 2 + length2 / 2 , Math.random() * 360 , Math.random() * 5 - 3 ); gArr.push(pp); } trace("Total: " + gArr.length); } private function run(evt:Event):void { bmd.lock(); bmd.colorTransform(bmd.rect , bmdctf); bmd.applyFilter(bmd , bmd.rect , new Point() , new BlurFilter(10 , 10 ,1)); var pppoint:Point = new Point(); for (var i:int = 0; i <=( gArr.length - 1 ); i++) { var pptemp:particleSample=gArr[i] as particleSample; pppoint=pptemp.pmove(); bmd.setPixel32(pppoint.x , pppoint.y , 0xffffff); } bmd.unlock(); } }// main class end }//package end