24
2015
08

魔棒边缘提取

ps中,选区的边界会生成蚂蚁线。下面我们就来视线一下这种效果。

前面已经介绍过魔棒的原理,用来生成一个选区。也介绍了蚂蚁线的生成。我们只需要在计算魔棒的选区的时候,把边界上的点记录下来,单独生成一张图片,然后用这张图片作为生成蚂蚁线时的遮罩。

源码如下:

package  {
	
	import flash.display.Bitmap;
	import flash.display.BitmapData;
	import flash.display.DisplayObjectContainer;
	import flash.display.Loader;
	import flash.display.MovieClip;
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.events.MouseEvent;
	import flash.geom.Point;
	import flash.geom.Rectangle;
	import flash.net.FileFilter;
	import flash.net.FileReference;
	
	
	public class Main extends MovieClip {
		
		
		private var bmd:BitmapData;
		private var bmpCon:Sprite;
		public function Main() {
			// constructor code
			
			stage ? initStage(null) : addEventListener(Event.ADDED_TO_STAGE, initStage);
			
		}
		
		private function initStage(e:Event):void 
		{
			removeEventListener(Event.ADDED_TO_STAGE, initStage);
			
			
			
			bmd = new Yu();
			var bmp:Bitmap = new Bitmap(bmd.clone());
			addChild(bmp);
			bmp.x = bmp.y = 50;
			
			
			bmpCon = new Sprite();
			addChild(bmpCon);
			bmpCon.name = "bmpCon";
			bmpCon.y = 430;
			bmpCon.x = 50;
			
			var bianyuan:Vector.= matting();
			var bmd2:BitmapData = new BitmapData(bmd.width, bmd.height, false, 0xffffff);
			bmd2.lock();
			var len:int = bianyuan.length;
			for (var i:int = 0; i < len;i+=2 ) {
				bmd2.setPixel(bianyuan[i], bianyuan[i + 1], 0x000000);
			}
			bmd2.unlock();
			bmpCon.addChild(new Bitmap(bmd2));
			
			var con:Sprite = new Sprite();
			addChild(con);
			con.x = bmp.x;
			con.y = bmp.y;
			var antLine:AntLine = new AntLine(bmd.width, bmd.height);
			con.addChild(antLine);
			var bmd3:BitmapData = new BitmapData(bmd.width, bmd.height, true, 0x00000000);
			bmd3.lock();
			for (i = 0; i < len;i+=2 ) {
				bmd3.setPixel32(bianyuan[i], bianyuan[i + 1], 0xff000000);
			}
			bmd3.unlock();
			var maskmc:Bitmap = new Bitmap(bmd3);
			con.addChild(maskmc);
			antLine.cacheAsBitmap = true;
			maskmc.cacheAsBitmap = true;
			antLine.mask = maskmc;
		}
		
		
		private var neighbor:Array = [[0, -1], [0, 1], [-1, 0], [1, 0]];
		
		/**
		 * 抠图,本程序的核心算法
		 */
		private function matting():Vector.
		{
			if (!bmd)
				return new Vector.();
			
			var bianyuan:Vector.= new Vector.();
			//拾取颜色
			var pickedColor:uint = 0xffffffff;
			
			var co1:int = rgb2gray(pickedColor);
			var thres:int = 32;
			
			var _w:int = bmd.width;
			var _h:int = bmd.height;
			var t:Number = new Date().getTime();
			var rect:Rectangle = new Rectangle(0, 0, _w, _h);
			var vec:Vector.= bmd.getVector(rect);
			var vec2:Vector.= new Vector.(_w * _h);
			check(10,10);
			bmd.setVector(rect, vec);
			timeTf.text = "用时" + (new Date().getTime() - t) + "ms";
			return bianyuan;
			
			function check(_x:int, _y:int):void
			{
				var stack:Array = [];
				stack.push(_x, _y);
				while (true)
				{
					if (stack.length= 0 && _x < _w && _y >= 0 && _y < _h)
					{
						var index:int = _x + _y * _w;
						if (!vec2[index])
						{
							vec2[index] = true;
							var pixel:uint = vec[index];
							var co2:int = rgb2gray(pixel);
							var cha:int = co1 - co2;
							if (cha < 0) cha = -cha;
							if (cha<thres)
							{
								vec[index] = 0x00000000;
								for (var i:int = 0; i < 4; i++)
								{
									var nei:Array = neighbor[i];
									stack.push(_x + nei[0], _y + nei[1]);
								}
							}
							else {
								bianyuan.push(_x, _y);//边缘提取,关键在于这句。
							}
						}
					}
				}
			
			} //end
		}
		private function rgb2gray(co:uint):int {
			var r:int = co >> 16 & 0xff;
			var g:int = co >> 8 & 0xff;
			var b:int = co & 0xff;
			return (r * 313524 + g * 615514 + b * 119538) >> 20;
		}
		//end
	}
	
}
import flash.display.Sprite;
import flash.events.Event;

class AntLine extends Sprite {
	private var _w:int;
	private var _h:int;
	public function AntLine(w:int,h:int){
		setSize(w,h);
	}
	public function setSize(w:int, h:int):void {
		_w = w;
		_h = h;
		addEventListener(Event.ENTER_FRAME, enterFrameHandler);
	}
	private var _offset:Number = 0;
	private function enterFrameHandler(e:Event):void 
	{
		_offset += 0.5;
		update();
	}
	private function update():void {
		graphics.clear();
		graphics.lineStyle(2, 0x000000, 1.0);
		var len:int = _w + _h;
		var x1:Number = i;
		var y1:Number = 0;
		var x2:Number = 0;
		var y2:Number = i;
		_offset = _offset % 6;
		for (var i:int = _offset; i < len; i += 6 ) {
			x1 = y2 = i;
			if (i>_w) {
				x1 = _w;
				y1 = i - _w;
			}
			if (i>_h) {
				y2 = _h;
				x2 = i - _h;
			}
			graphics.moveTo(x1, y1);
			graphics.lineTo(x2, y2);
		}
	}
}

效果:

获得 Adobe Flash Player

源码打包下载

« 上一篇下一篇 »

相关文章:

蚂蚁线  (2015-8-24 13:5:20)

发表评论:

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。