BitmapData类详解及应用(一)
BitmapData类表示一个由像素组成的位图,包含了很多内建的方法来控制和处理位图。
h%o z{#eI0
sC:xa Umn+B$G4s0
一、在程序里创建位图并显示
要创建一个位图可以用如下方法:
I;P]-i*~a,o'g$E1O0
var bmd:BitmapData = new BitmapData(width,height,transparent,fillColor);闪吧新社区E2B3I$^3|{9u
width:位图的宽度;
3B5g2i Cl]1[d0
height:位图的高度;
2bK&|SI\0
transparent:布尔值,表示是否显示alpha通道,默认值为false;闪吧新社区X5J'E3T!N ge z
fillColor:表示背景颜色的填充颜色,可以是24位和32位颜色,默认值为0xffffffff;
!gC4NcN0
闪吧新社区%`(f&Q*x8zH5{ L
如要创建一个100*100,透明白色背景色的位图:
J(H+qdRn0
var bmd:BitmapData = new BitmapData(100,100,true,0x00ffffff);
H*WKY(K0Wn~t6e0
上面的代码只是在内存中创建了一个位图,如果测试则无显示,还需将其加入显示列表才能显示。由于只有flash.display.DisplayObject的子类可以加入显示列表,而BitmapData类继承自Object,因而无法加入显示列表,此时需要用BitmapData类的封装类Bitmap类,继续加入代码,如下:闪吧新社区%j-d.e,I`3v8[ D#qx
var bm:Bitmap = new Bitmap(bmd);闪吧新社区l8Md3_3X5[G
addChild(bm);
)V6I+KkX\`0
二、在位图上绘制其他对象
由BitmapData类默认创建的位图,仅是一个定义了宽度、高度和背景色的位图,由于BitmapData类没有基本的画线,曲线的方法,要想向位图上添加其他对象,我们可以先MovieClip或者Sprite对象里画好,然后通过BitmapData类的draw()方法添加到位图之上,draw()方法介绍如下:
bAP5q"O1Te0
draw(source:IBitmapDrawable, matrix:Matrix = null, colorTransform:ColorTransform = null, blendMode:String = null, clipRect:Rectangle = null, smoothing:Boolean = false):void闪吧新社区)SC^/VJG9QN
source:要绘制到 BitmapData 对象的显示对象或 BitmapData 对象。闪吧新社区%M&D)K v#gY2Z7X4L
matrix:一个 Matrix 对象,用于处理(缩放、旋转或转换坐标)source对象,如果要此参数而又不想其产生作用可以用null替代。闪吧新社区O3wolB5A t
colorTransform:一个 ColorTransform 对象,用于调整位图的颜色值。如果要此参数而又不想其产生作用可以用new ColorTransform()创建对象替代此参数。闪吧新社区 `U7Ai[(]]"\6i6f
blendMode:来自 flash.display.BlendMode 类的一个字符串值,指定要应用于所生成位图的混合模式。闪吧新社区L|?*D.]~#b0@G
clipRect:一个 Rectangle 对象,定义要绘制的源对象的区域。 如果不提供此值,则不会进行剪裁,并且将绘制整个源对象。闪吧新社区B0H;k M3Y
smoothing:一个布尔值,只有在source为BitmapData对象时有效,用于确定因在 matrix 参数中指定缩放或旋转而对 BitmapData 对象进行缩放或旋转以后,是否对该对象进行平滑处理。设为true时会比设为false时更增加系统负担。
/c4E;Q)\.I ^0
闪吧新社区.Y&w ^ y9F1C6f[Y
介绍完draw()方法,现在就来看如下一个应用代码:先创建BitmapData,Sprite实例,在Sprite里画一个椭圆,然后将Sprite再绘制到BitmapData实例上。闪吧新社区\ ^3Ro%G7v$lUgx
var bmd:BitmapData = new BitmapData(100,100,true,0x00ffffff);
!n9w2a2Ya(Bm6MAT0
var bm:Bitmap = new Bitmap(bmd);
Yny,b\UF&J4F0
var sprite:Sprite = new Sprite();
0v4`"b5LX![U#@^J0
sprite.graphics.beginFill(0xff0000);
&vYg"NS;][7g}S0
sprite.graphics.drawEllipse(0,25,100,50);闪吧新社区#^pYy4\i O:E*w oq
sprite.graphics.endFill();
#i^)y'z ODddc0
bmd.draw(sprite);闪吧新社区|&Q-y|A8iF_
此处椭圆的坐标(0,25)在位图100*100的范围之内,如果椭圆的坐标为(50,0),则位图上只会显示一个半椭圆,也就是说要绘制到位图上的可显示对象,要显示在位图上跟可视化对象,位图对象的位置,坐标都有关系。
Z+u~#w9XqF0
三、载入外部图像到位图上
可以使用flash.display.Loader类加载图片,用Loader类的complete事件监听是否加载完成。代码如下:闪吧新社区+B4t&Et?]6x
//加载图像
j*@ IZ)x!p0
var loader:Loader = new Loader();
oLxyt`|0
loader.load(new URLRequest(“image.jpg”));//image.jpg与此文件同一目录
4yS)fic"dk0
//监听complete事件
%DS4fP_ gDA0
loader.contentLoaderInfo.addEventListener(“Event.COMPLETE”,onComplete);
Z cw \8]d2H9J1@W;S0
a|#ccFav*a@0
function onComplete(event:Event):void{
Vp3Xjc6F1}0
var bm:Bitmap = Bitmap(loader.content);
6t-lKv.vM"w0
var bmd:BitmapData = bm.bitmapData;
(C9TdB3`!M0
addChild(bm);
SIE*_@S{/},o0
}闪吧新社区&@6{%cB {s#F
此处onComplete处理函数编译可能会有安全方面的错误。
S(M'z#S Fo.G M`0
通过loader加载的如果是.swf,则loader.content为MovieClip类型;如果载入的是图像,则loader.content为Bitmap类型。通过Bitmap类的bitmapData属性就可以访问导入的图像,这样就可以修改或者重建导入的图像。闪吧新社区$K#cMv7u+[
四、处理像素
1、可以使用setPixel(),getPixel(),setPixel32(),getPixel32()对位图中的单个像素进行处理。各方法使用简单,定义如下:闪吧新社区YY]|G9t
getPixel(x:int, y:int):uint;-----------------------------------------------①
J;R*Q8OF w+a*GT0
getPixel32(x:int,y:int):uint;---------------------------------------------②
!E3AZ7h&c6f$r g'r0
setPixel(x:int, y:int, color:uint):void;-----------------------------------③
cq F*SJ ]0
setPixel32(x:int,y:int,color:uint):void;---------------------------------④闪吧新社区4C q*k QV6`h\5k
下面的代码创建一个32位颜色的,白色背景位图,并添加1000个随机位置,半透明的红色像素,如下:闪吧新社区4h,x,[FrK'T
var bmd:BitmapData = new BitmapData(100,100,true,0xffffffff);闪吧新社区;K@'AMs7kJ
var bm:Bitmap = new Bitmap(bmd);闪吧新社区2z } L#zbc\
for(var i:uint=0;i:<1000;i++){
i"K*? ^`/D0
bmd.setPixel32(Math.random()*100,Math.random()*100,0x88ff0000);
M4|%].ev r j$_'d0
}闪吧新社区(^ Het7yT'?
addChild(bm);闪吧新社区1Y#B'D1U/d
让上面①--④中x,y参数满足一定的函数关系,则可让像素摆成一定关系的形状或曲线,如下代码(画圆):闪吧新社区c|bA3_:xm
var centerX:Number = stage.stageWidth/2;
.e7_.vV?@0
var centerY:Number = stage.stageHeight/2;闪吧新社区,Zc%Ra2y{Cd-]
var range:Number = 100;闪吧新社区 i.eM.K#`u-z `
for(var i:int=0;i<360;i++){
F V-h6B:b%v{ }V0
var tx:Number = centerX+range*Math.cos(i*Math.PI/180);闪吧新社区O1xKFyYw
var ty:Number = centery+range*Math.sin(i*Math.PI/180);闪吧新社区hv I V*t4Y
bmd.setPixel32(tx,ty,color);闪吧新社区T:Q5Tp;OPeh
}
:\&F)IU6B.O0
闪吧新社区s)R0u3|O
下面的代码是setPixel()的应用,如下(获取光标处的颜色值):
_,|!t;qf3eQ0
var txt:TextField = new TextField();
7D3i&KO ~0
var bmd:BitmapData = new BitmapData(100,100,true,0xffffffff);
G[^ l5Hg7l!A'?0
var bm:Bitmap = new Bitmap(bmd);
U4BFK6Zl0v0
addChild(bm);闪吧新社区y z OhhHAY
bmd.noise(1000,0,255,1|2|4,false);
*\:c8A"a,qk;pE0
addChild(txt);
o,K6Pv6O d(o%Y/Y0
addEventListener(Event.ENTER_FRAME,onEnterFrame);
BE Ok1j$X0
SUXp0QT0OXz0
function onEnterFrame(event:Event):void{闪吧新社区:qT/EN?S Z8j V
var color:uint = bmd.getPixel32(mouseX,mouseY);闪吧新社区tM(qenh n
txt.text = “#”+color.toString(16).toUpperCase();闪吧新社区pnx$[N}!z
}
U(CvR6NMh0
闪吧新社区HE4e0AVU o
2、利用copyPixels()方法拷贝像素。此方法在目标 BitmapData 对象的目标点将源图像的矩形区域复制为同样大小的矩形区域。闪吧新社区7\1K7e;_:I1gt
copyPixels(sourceBitmapData:BitmapData,sourceRect:Rectangle,destPoint:Point,alphaBitmapData:BitmapData = null, alphaPoint:Point = null, mergeAlpha:Boolean = false):void
jN*B|1{&G5`1i)sJ;Q0
0z;b'N2_(u0
sourceBitmapData:要从中复制的源位图图像,是一个BitmapData实例;
(Yx ])l{1I I0
sourceRect:源位图上的一个矩形区域;
1N8l*O$s3n)f#C0
destPoint:目标点,表示将在其中放置新像素的矩形区域的坐上角。
!MT1zbI?NX)^W0
alphaBitmapData:第二个 Alpha BitmapData 对象源。
hG] b f-h0|2k0
alphaPoint:alpha BitmapData 对象源中与 sourceRect 参数的左上角对应的点。闪吧新社区#d-NzG(rZ6]i%E
mergeAlpha:表示复制的像素是否带有alpha通道,true时表示带alpha通道。闪吧新社区-`ii#c6}Cne
PUaW(k/qu0
3、利用copyChannel()拷贝通道。将数据从另一个 BitmapData 对象或当前 BitmapData 对象的一个通道传输到当前 BitmapData 对象的某个通道中。闪吧新社区&D6b[ M gw!Sot1O
copyChannel(sourceBitmapData:BitmapData,sourceRect:Rectangle,destPoint:Point, sourceChannel:uint, destChannel:uint):void闪吧新社区:^v8Kq]%[0vq
前三个参数跟copyPixels()前三个参数一样, sourceChannel,destChannel分别是源通道和目的通道,他们可以的取值可能是下面的某一种:
vT'L}q&N*CT2z0
l BitmapDataChannel.RED
p2v,^9Y%k$G:EQ0
l BitmapDataChannel.GREEN
$[9Gk6T6KE~;q0
l BitmapDataChannel.BLUE
-o'kiBBa+m*[A0
l BitmapDataChannel.ALPHA
"q5S"j,HG k4c$p$U0
闪吧新社区/fG7@$q6@ ^ V,V3R
五、位图的填充
1、用指定的颜色填充位图的一个矩形区域。
5Ei"J,m;KG ?'FaK0
Kd&eleJ}d-|4V0
用fillRect()即可填充位图的一个矩形区域,fillRect()的详细用法如下:
#WW X3uZ"i;n,C0
fillRect(rect:Rectangle, color:uint):void闪吧新社区s%HYKp
rect:要填充的矩形区域;
y TX7F[4DN&D(A0
color;要填充的ARGB颜色
:k?`/? Y2f0
下面的代码是填充位图中一个矩形区域为红色,如下:
)gg,Q2c!^0
var bmd:BitmapData = new BitmapData(100,100,true,0xffffffff);闪吧新社区9G&I+~ J QH wy5aP0?y6Em
var bm:Bitmap = new Bitmap(bm);
7E:H m8tuP$^3e0
addChild(bm);闪吧新社区 C,a6T&~ N3b o
bmd.fillRect(new Rectangle(0,0,25,25),0xffff0000);
!\y;K{ sxd;Cq2UBQ0
7w9v _6A#`'kY0
2、用指定的颜色填充位图的一个不规则区域。
a6|I:d ^ IO\ Yi0A#P0
闪吧新社区 W_2kCXB(DC:A j9i ~
用floodFill(x:int,y:int,color:uint):void可以对位图进行倾倒填充,从(x,y)坐标开始填充一种特定的颜色,下面的代码,先创建一些方框一个位图,然后鼠标点击方框就会用红色填充方框,如下:
_1U5qPX{o J0
var sprite:Sprite = new Sprite();
.@/Mwia a0
addChild(sprite);
j E$j;KHN0
var bmd:BitmapData = new BitmapData(stage.stageWidth,stage.stageHeight,true,0xffffffff);闪吧新社区L~,VF^y7Xa
var bm:Bitmap = new Bitmap(bmd);
?:^fn#[0
for(var i:int=0;i<20;i++){闪吧新社区4v/O W;T'h2q
var tx:Number = Math.random()*stage.stageWidth;闪吧新社区;W z)SR9H bD
var ty:Number = Math.random()*stage.stageHeight;
6V]@WLs~XR0
var rect:Rectangle=new Rectangle(tx,ty,20,20);闪吧新社区0i%{ h2^FU4W#e z
bmd.fillRect(rect,0xffff0000);
/uh*V W#qv!I0
}
M{gbe#~0
sprite.addChild(bm);
3L|_ ^%G;u?cWM0
sprite.addEventListener(MouseEvent.MOUSE_DOWN,onMouseDown);
8PO4bx8y6^N0
闪吧新社区(T/` K-_R&Ea1L.P
function onMouseDown(event:MouseEvent):void{
OT r}$Jm'CS0
bmd.floodFill(mouseX,mouseY,0xffff0000);闪吧新社区/]/@)z6u:r2V:S1ZK-S
}