一、Flex中关于图片的概念有以下几个:
Bitmap:数据类。用于表示位图的显示对象。
BitmapData:数据类。用于处理位图对象的数据(像素)。BitmapData存储像素数据的数组,可通过BitmapData对位图的像素进行直接操作。
Image:组件类。Image是一个组件,用于显示位图。
Image和Bitmap的不同:Bitmap和Image继承自DisplayObject,两者都可以在界面上显示,但Bitmap和Sprite一样,没有继承自可视化对象的基类UIComponent,所有不能直接加到容器,而Image则是继承自UIComponent的可视化组件。
private var loader:Loader=new Loader();
protected function application1_creationCompleteHandler(event:FlexEvent):void
{
var img:Image=new Image();
img.source="resource/copy_normal.png";
this.addElement(img);
loader.contentLoaderInfo.addEventListener(Event.COMPLETE,loadCompleteHandler);
loader.load(new URLRequest("resource/copy_normal.png"));
}
private function loadCompleteHandler(evt:Event):void{
var bitmap:Bitmap=Bitmap(loader.content);
var comp:UIComponent=new UIComponent();
comp.addChild(bitmap);
comp.x=200;
this.addElement(comp);
}
二、图片的加载方式
1、给Image指定Source
/*直接指定资源*/
var img:Image=new Image();
img.source="resource/copy_normal.png";
this.addElement(img);
/*使用嵌入资源*/
var img:Image=new Image();
img.source=texture;
this.addElement(img);
this.addElement(img);
<fx:Declarations>
<!--直接嵌入资源-->
<s:Image id="img" source="@Embed('resource/copy_normal.png')"/>
</fx:Declarations>
2、加载图片内容到Bitmap
Bitmap的图片数据来源有两种,一种是实例化的时候给它设置BitmapData,但很多时候是需要直接从图片文件中读取数据,而BitmapData反过来需要从Bitmap得到,所以就得用第二种方式,即使用加载器加载。
加载器主要有两个,Loader和URLLoader。
使用Loader可直接加载显示对象,图片加载完成后直接把数据转为Bitmap即可显示。
private var loader:Loader;
protected function group1_creationCompleteHandler(event:FlexEvent):void
{
loader=new Loader();
loader.contentLoaderInfo.addEventListener(Event.COMPLETE,loadComplete);
loader.load(new URLRequest("resource/copy_normal.png"));
}
private function loadComplete(evt:Event):void{
var bitmap:Bitmap=Bitmap(loader.content);
var comp:UIComponent=new UIComponent();
comp.addChild(bitmap);
this.addElement(comp);
}
URLLoader以文本、二进制数据或URL编码的形式从URL下载数据。可设置URLDataFormat来指定加载完成后的数据格式,有TEXT,BINARYT VARIABLES三种。URLLoader加载完成后只能得到数据,不能直接添加到显示对象。要将图片显示有两种方式。
第一种是使用Loader对URLLoader得到的二进制数据进行二次加载。
private var urLoader:URLLoader;
private var loader:Loader;
protected function group1_creationCompleteHandler(event:FlexEvent):void
{
urLoader=new URLLoader();
loader=new Loader();
urLoader.dataFormat=URLLoaderDataFormat.BINARY;
urLoader.addEventListener(Event.COMPLETE,urlLoadComplete);
urLoader.load(new URLRequest("resource/copy_normal.png"));
}
private function urlLoadComplete(evt:Event):void{
var bytes:ByteArray=urLoader.data;
loader.contentLoaderInfo.addEventListener(Event.COMPLETE,loadComplete);
loader.loadBytes(bytes);
}
private function loadComplete(evt:Event):void{
var bitmapData:BitmapData=new BitmapData(200,200);
bitmapData.draw(loader.content);
var bitmap:Bitmap=new Bitmap(bitmapData);
var comp:UIComponent=new UIComponent();
comp.addChild(bitmap);
this.addElement(comp);
}
第二种是根据得到的二进制数据ByteArray生成BitmapData。但这种方式其实并不实用,URLLoader加载得到的数据并不能直接通过setPixes赋给BitmapData。
总结:加载图片用Loader会比URLLoader更加省时省力,因为URLLoader得到的数据不能直接显示,还必须得通过Loader再加载一次才能显示。但URLLoader能够加载的东西更多,功能也更强大。
3、BitmapData与ByteArray之间的转换
BitmapData与ByteArray之间的转换类似于序列化与反序列化。
var bmData:BitmapData=new BitmapData(img.width,img.height);
bmData.draw(img)
var bitmap:Bitmap=new Bitmap(bmData);
var comp:UIComponent=new UIComponent();
comp.addChild(bitmap)
bitmap.x = 200
this.addElement(comp)
var bmData2:BitmapData=new BitmapData(bmData.width,bmData.height);
var pixels:ByteArray=bmData.getPixels(bmData.rect);
pixels.position = 0
//外层循环为高,内层循环为宽
for(var i:uint=0;i<bmData.height;i++){
for(var j:uint=0;j<bmData.width;j++){
bmData2.setPixel(j,i,pixels.readUnsignedInt());
}
}
var bitmap2:Bitmap=new Bitmap(bmData2);
comp.addChild(bitmap2)
bitmap2.y = 200
4、序列化与反序列化
var bmData:BitmapData=new BitmapData(img.width,img.height);
bmData.draw(img)
var comp:UIComponent=new UIComponent();
comp.y = 200
this.addElement(comp)
//序列化
var pixels:ByteArray=bmData.getPixels(bmData.rect);
var jpgEncoder:JPEGEncoder=new JPEGEncoder();
var picBytes:ByteArray=jpgEncoder.encode(bmData);
var srcBytes:ByteArray=jpgEncoder.encodeByteArray(pixels,bmData.width,bmData.height);
//反序列化
var loader:Loader=new Loader();
loader.contentLoaderInfo.addEventListener(Event.COMPLETE,function(evt:Event){
var bitmap:Bitmap=Bitmap(loader.content);
comp.addChild(bitmap);
});
loader.loadBytes(picBytes);
var loader2:Loader=new Loader();
loader2.contentLoaderInfo.addEventListener(Event.COMPLETE,function(evt:Event){
var bitmap:Bitmap=Bitmap(loader2.content);
bitmap.x=200;
comp.addChild(bitmap);
});
loader2.loadBytes(srcBytes)
三、图片局部显示技术
1、使用遮罩
mask是显示对象基类DisplayObject的一个属性,被mask蒙版的部分将显示,其它部分将被隐藏。遮罩源mask同样是一个DisplayObject,但如果mask是Sprite或Shape等绘制对象的话,必须使用填充才能使遮罩出现,如果使用线条的话将看不到被遮罩对象。
var sp:Sprite=new Sprite();
img.mask = sp
sp.graphics.beginFill(1, 0xffffff)
sp.graphics.drawCircle(30, 30, 30)
sp.graphics.endFill()
如果要对遮罩源进行变换,则必须加到显示列表中。
protected function group1_creationCompleteHandler(event : FlexEvent) : void
{
img.mask = sp;
sp.graphics.beginFill(1, 0xffffff);
sp.graphics.drawCircle(30, 30, 30);
sp.graphics.endFill();
//这三行代码是必须的
var comp : UIComponent = new UIComponent();
comp.addChild(sp);
this.addElement(comp);
this.addEventListener(MouseEvent.CLICK, mouseClickHandler);
}
private function mouseClickHandler(evt : MouseEvent) : void
{
sp.x += 5;
if (sp.x > img.width)
{
sp.x = 0;
}
}
2、使用UV贴图
UV贴图的功能十分强大,不仅能够实现图片部分显示,而且可以减轻组件和重量,提高系统效率。UV贴图是画在显示对象的Graphics上面的,和画线、填充一样。所以,无论界面上需要同时显示多少图片,界面上只需要一个显示对象。