flex flash解决png图像透明部分处理的几种方案

在做游戏地图和其它项目时候需要对png图像的透明部分进行处理,下面对我用过的几种方法做总结。每种方法都有自己的优缺点根据需要使用。

第一种方案是使用InteractivePNG(相对于显示对象处理)

flash上用就不说了官方有例子,在flex上使用需要做稍许改动,只要把extends由MovieClip改成Image就可以了,但是这样改有一个小bug,使用的时候需要注意。在Image指定source时需要指定一个绑定对象而不能使用图像路径的字符串。

 

[Embed(source="1.png")]

private var background:Class;

<ns1:InteractivePNG x="33" y="31" width="308" height="222" id="img" source="background"/>

第二种通过容器的像素点检测(相对于容器处理)

对容器添加监听鼠标事件

记录鼠标的xy位置,遍历一边所有容器里的显示对象(由于容器对象的Index问题需要反向遍历显示对象),判断该点的alpha是否大于0xff(取颜色的时候需要转换一下坐标系)。

第三种使用碰撞检测(相对于容器处理)

写一个静态方法检测,检测像素级的单击检测,类似与第二种方法。

 

public static function realHitTest(object:DisplayObject, point:Point):Boolean {

if(object is BitmapData) {

return (object as BitmapData).hitTest(new Point(0,0), 0, object.globalToLocal(point));

}

else {

if(!object.hitTestPoint(point.x, point.y, true)) {

return false;

}

else {

var bmapData:BitmapData = new BitmapData(object.width, object.height, true, 0x00000000);

bmapData.draw(object, new Matrix());

var returnVal:Boolean = bmapData.hitTest(new Point(0,0), 0, object.globalToLocal(point));

bmapData.dispose();

return returnVal;

}

}

}

 

第四种是用hitArea来实现,网上有现成的例子,就是遍历一边该图像的像素点来重绘图像的hitArea(相对于显示对象本身处理)

如果图像很大估计会很慢

package

{

import flash.display.BitmapData;

import flash.display.DisplayObject;

import flash.display.Sprite;

import flash.events.Event;

import flash.geom.Matrix;

import flash.utils.setTimeout;

import mx.controls.Image;

public class DisplayImage extends Image

{

private var ht:Sprite = new Sprite();

public function DisplayImage()

{

addChild(ht);

hitArea = ht;

//指定hitArea为ht对象

ht.visible = false;

ht.mouseEnabled = false;

mouseChildren = false;

addEventListener(Event.COMPLETE,complete,false,99,true);

setTimeout(update,50)

}

private function complete(e:Event):void

{

setTimeout(update,50)

}

private function update():void

{

if(!content)return;

var loader:DisplayObject = content.parent as DisplayObject;

var bit:BitmapData = new BitmapData(loader.width,loader.height,true,0x00000000);

var mat:Matrix = new Matrix();

mat.scale(loader.scaleX,loader.scaleY);

bit.draw(loader,mat);

//重绘图象到bit

ht.graphics.clear();

ht.graphics.beginFill(0);

for(var x:uint=0;x<bit.width;x++)

{

for(var y:uint=0;y<bit.height;y++)

{

if(bit.getPixel32(x,y))ht.graphics.drawRect(x,y,1,1);

}

}

//以graphics画出bit的无透明区域

ht.graphics.endFill();

}

}

}

总结对于透明检测归根到底还是像素点的检测只是方法变通而已。处理方式分为针对容器和针对显示对象本身两种方式

 

呵呵,最后再加一个方法,获得“真实”图像大小的方法处理那些有大量空白区域的图像。

 

public function getBitmapCroppedOutWhitespace(bd:BitmapData):Bitmap {

var rect:Rectangle = bd.getColorBoundsRect(0xFFFFFF, 0x00000000, false);

var bmd2:BitmapData = new BitmapData(rect.width, rect.height, true, 0x00000000);

bmd2.draw(bd, new Matrix(1,0,0,1, -rect.x, -rect.y));

var bmp:Bitmap = new Bitmap(bmd2);

return bmp;

}

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值