忽略PNG透明区域的事件(AS/Flash)

此文出现源于忽略PNG透明区域的事件(Flex)...
下面是纯as的实现..用的是Loader..帮群里的朋友写的实例
详情的思路什么的就不说了..看上面的地址

效果(左边的PNGLoader加截的png忽略透明,右边的为普通Loader):



代码:
PNGLoader.as
package net.l4cd.display
{
	import flash.display.BitmapData;
	import flash.display.Loader;
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.events.IOErrorEvent;
	import flash.events.ProgressEvent;
	import flash.geom.Matrix;
	import flash.net.URLRequest;
	import flash.system.LoaderContext;
	import flash.utils.ByteArray;

	/**
	 * PNGLoader,主要解决png图片透明像素处事件的问题 
	 * @author L4cd.Net
	 * 
	 */	
	public class PNGLoader extends Sprite
	{
		private var loader:Loader = new Loader();
		private var hit:Sprite = new Sprite();
		public function PNGLoader()
		{
			addChild(loader);
			addChild(hit);
			hit.visible = false;
            hit.mouseEnabled = false;
            mouseChildren = false;
			hitArea = hit;
			loader.contentLoaderInfo.addEventListener(Event.COMPLETE,complete);
			loader.contentLoaderInfo.addEventListener(IOErrorEvent.IO_ERROR,error);
			loader.contentLoaderInfo.addEventListener(ProgressEvent.PROGRESS,progress);
		}
		private function complete(e:Event):void
		{
			dispatchEvent(e);
			update();
		}
		private function error(e:IOErrorEvent):void
		{
			dispatchEvent(e);
		}
		private function progress(e:ProgressEvent):void
		{
			dispatchEvent(e);
		}
		public function load(request:URLRequest,context:LoaderContext=null):void
		{
			loader.load(request,context);
			clear();
		}
		public function loadBytes(bytes:ByteArray,context:LoaderContext=null):void
		{
			loader.loadBytes(bytes,context);
			clear();
		}
		public function unload():void
		{
			loader.unload();
			clear();
		}
		public function close():void
		{
			loader.close();
			clear();
		}
		private function clear():void
		{
			hit.graphics.clear();
		}
		private function update():void
		{
			if(!loader.content)return;
			var bit:BitmapData = new BitmapData(loader.width,loader.height,true,0x00000000);
			bit.draw(loader);
			//重绘图象到bit
			clear();
			hit.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))hit.graphics.drawRect(x,y,1,1);
				}
			}
			//以graphics画出bit的无透明区域
			hit.graphics.endFill();
		}
	}
}

PNGLoaderExample.as
package
{
	import flash.display.Loader;
	import flash.display.Sprite;
	import flash.events.MouseEvent;
	import flash.filters.GlowFilter;
	import flash.net.URLRequest;
	
	import net.l4cd.display.PNGLoader;


	[SWF(width="600",height="400")]
	/**
	 * PNGLoaderExample 
	 * @author L4cd.Net
	 * 
	 */	
	public class PNGLoaderExample extends Sprite
	{
		public function PNGLoaderExample()
		{
			var pl:PNGLoader = new PNGLoader();
			pl.load(new URLRequest("10020601.png"));
			addChild(pl);
			pl.y = 20;
			pl.addEventListener(MouseEvent.ROLL_OUT,o);
			pl.addEventListener(MouseEvent.ROLL_OVER,o);
			
			var ld:Loader = new Loader();
			ld.load(new URLRequest("10020601.png"));
			addChild(ld);
			ld.x = 320;
			ld.y = 20;
			ld.addEventListener(MouseEvent.ROLL_OUT,o);
			ld.addEventListener(MouseEvent.ROLL_OVER,o);
			
			
			graphics.lineStyle(1);
			graphics.drawRect(20,20,250,250);
			
			graphics.drawRect(320,20,250,250);
		}
		private function o(e:MouseEvent):void
		{
			e.target.filters = (e.type == MouseEvent.ROLL_OVER)?[new GlowFilter()]:[];
		}
	}
}


分类: ACTIONSCRIPT , 标签: , , , , ,

发布评论

注:邮箱址些公用作显示头像与回复之用 , * 号所在的选择必须填写.

*



8 Responses to 忽略PNG透明区域的事件(AS/Flash)


  1. 在for那里扫描的时候,可以采用异步的方式,可以降低cpu的占用


  2. 哎。大师就是大师,
    刚刚试了PNGEncoder.encode().也达不到效果。
    试问大师:还有没有别的途径达到此效果呢?


  3. 呵呵,没仔细看,是用的图片太小了。用Loader确实达不到效果。


  4. 哎呀,发的代码怎么看不见?


  5. 你好,好久没来你这了。
    稍稍看了一下你这个Demo,第一感觉效率肯定很低,然后小小的质疑了一下,用Loader真的就不可以实现你那个朋友需要的效果吗?
    随后我自己做了个测试。证明用Loader也是可以的。不知道你是怎么测试的,我的代码如下:


    • 关于这个方法的效率问题..
      对于大图片当然是很低的..
      不过对于实际的应用..
      一般需在这种情况的大多数都是小图标或皮肤之类的应用..
      其实还是可以接受的..
      没有绝对好的方法..
      结合程序的条件与限制选择最适合的方法就可以了..


    • 另外..
      在for循环语句里...
      调整历遍的密度..从1px改成2px或4px..
      用精确度换取时间..也是一个可取的方法..