24
2015
08

魔棒工具

参考:http://hanyeah.com/blog/post/%E5%9B%BE%E5%83%8F%E4%B9%8B%E9%AD%94%E6%A3%92%E5%B7%A5%E5%85%B7%E5%AE%9E%E7%8E%B0.html

用as简单做了一下,没有用颜色的灰度值来比较,而是直接使用ARGB分量。

源码:

用到了PNGEncoder和bit01组件库。

package
{
	
	import com.adobe.images.PNGEncoder;
	import com.bit101.components.ColorChooser;
	import com.bit101.components.ScrollPane;
	import com.bit101.components.Slider;
	import com.bit101.components.Style;
	import flash.display.Bitmap;
	import flash.display.BitmapData;
	import flash.display.DisplayObjectContainer;
	import flash.display.Loader;
	import flash.display.MovieClip;
	import flash.display.Shape;
	import flash.display.SimpleButton;
	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;
	import flash.text.TextField;
	import flash.utils.ByteArray;
	
	public class Main extends MovieClip
	{
		
		public var dktpBtn:SimpleButton;
		public var ktBtn:SimpleButton;
		public var cxBtn:SimpleButton;
		public var bcBtn:SimpleButton;
		public var tf1:TextField;
		public var tf20:TextField;
		public var tf21:TextField;
		public var tf22:TextField;
		public var tf23:TextField;
		public var timeTf:TextField;
		public var pen:MovieClip;
		
		private var panel:ScrollPane;
		private var slider:Slider;
		private var bmpCon:Sprite;
		private var colorCube:Shape;
		private var colorPicker:ColorChooser;
		
		private var fileRefrence:FileReference = new FileReference();
		private var fileFilter:FileFilter = new FileFilter("图片文件(*.jpg,*.png,*.gif)", "*.jpg;*.png;*.gif");
		private var ld:Loader = new Loader();
		private var bmd:BitmapData;
		private var pickedColor:uint;
		private var fileName:String;
		private var arr:Array = [];
		private var max_cx:int = 10; //最大撤销次数
		
		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);
			
			Style.fontSize = 11;
			Style.embedFonts = false;
			Style.fontName = 'Microsoft YaHei';
			
			panel = new ScrollPane(this, 0, 0);
			panel.setSize(800, 600);
			
			slider = new Slider(Slider.HORIZONTAL, this, 845, 380, sliderChanged);
			slider.maximum = 2;
			slider.minimum = 0.3;
			
			bmpCon = new Sprite();
			panel.content.addChild(bmpCon);
			bmpCon.name = "bmpCon";
			
			colorCube = new Shape();
			addChild(colorCube);
			colorCube.x = tf1.x + tf1.width;
			colorCube.y = tf1.y;
			
			colorPicker = new ColorChooser(this, 890, 440, 0xffffff, bgColorChanged);
			colorPicker.usePopup = true;
			bgColorChanged(null);
			
			pickedColor = 0x00000000;
			updateColor();
			slider.value = 1;
			pen.mouseEnabled = false;
			pen.visible = false;
			addChild(pen);
			
			tf20.restrict = "0-9";
			tf20.maxChars = 3;
			tf21.restrict = "0-9";
			tf21.maxChars = 3;
			tf22.restrict = "0-9";
			tf22.maxChars = 3;
			tf23.restrict = "0-9";
			tf23.maxChars = 3;
			
			addEventListener(MouseEvent.CLICK, clickHandler);
			fileRefrence.addEventListener(Event.SELECT, fileHandler);
			fileRefrence.addEventListener(Event.COMPLETE, fileHandler);
			ld.contentLoaderInfo.addEventListener(Event.COMPLETE, onImgLoaded);
			addEventListener(Event.ENTER_FRAME, enterFramehandler);
		}
		
		private function bgColorChanged(e:Event):void 
		{
			panel.color = colorPicker.value;
		}
		
		/**
		 * enterFrame
		 * @param	e
		 */
		private function enterFramehandler(e:Event):void
		{
			pen.x = mouseX;
			pen.y = mouseY;
		}
		
		/**
		 * 图片加载完成
		 * @param	e
		 */
		private function onImgLoaded(e:Event):void
		{
			fileName = fileRefrence.name;
			arr = [];
			var bmp:Bitmap = ld.content as Bitmap;
			bmd = bmp.bitmapData;
			updateBmd(true);
		}
		
		/**
		 * 更新图片显示
		 * @param	initFlag	是否更新位置及缩放状态
		 */
		private function updateBmd(initFlag:Boolean = false):void
		{
			clear(bmpCon);
			bmpCon.addChild(new Bitmap(bmd));
			if (initFlag)
			{
				slider.value = 1;
				sliderChanged(null);
			}
		}
		
		/**
		 * 清空显示容器
		 * @param	con
		 */
		private function clear(con:DisplayObjectContainer):void
		{
			while (con.numChildren)
			{
				con.removeChildAt(0);
			}
		}
		
		/**
		 * 浏览打开图片管理
		 * @param	e
		 */
		private function fileHandler(e:Event):void
		{
			switch (e.type)
			{
				case Event.SELECT: 
					fileRefrence.load();
					break;
				case Event.COMPLETE: 
					ld.loadBytes(fileRefrence.data);
					break;
			}
		}
		
		/**
		 * 点击管理
		 * @param	e
		 */
		private function clickHandler(e:MouseEvent):void
		{
			switch (e.target.name)
			{
				case "dktpBtn": 
					fileRefrence.browse([fileFilter]);
					break;
				case "ktBtn": 
					pen.visible = !pen.visible;
					break;
				case "cxBtn": 
					revoke();
					break;
				case "bcBtn": 
					save();
					break;
				case "bmpCon": 
					if (pen.visible)
					{
						matting();
					}
					break;
				default: 
					break;
			}
		}
		private var neighbor:Array = [[0, -1], [0, 1], [-1, 0], [1, 0]];
		
		/**
		 * 抠图,本程序的核心算法
		 */
		private function matting():void
		{
			if (!bmd)
				return;
			
			//拾取颜色
			var p:Point = new Point(stage.mouseX, stage.mouseY);
			p = bmpCon.globalToLocal(p);
			pickedColor = bmd.getPixel32(p.x, p.y);
			updateColor();
			
			var obj:Object = colorResolve(pickedColor);
			var thresholdObj:Object = {};
			thresholdObj.a = int(tf20.text);
			thresholdObj.r = int(tf21.text);
			thresholdObj.g = int(tf22.text);
			thresholdObj.b = int(tf23.text);
			
			var _w:int = bmd.width;
			var _h:int = bmd.height;
			arr.push(bmd.clone());
			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(p.x, p.y);
			bmd.setVector(rect, vec);
			timeTf.text = "用时" + (new Date().getTime() - t) + "ms";
			
			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 obj2:Object = colorResolve(pixel);
							if (comparison(obj2))
							{
								vec[index] = 0x00000000;
								for (var i:int = 0; i < 4; i++)
								{
									var nei:Array = neighbor[i];
									stack.push(_x + nei[0], _y + nei[1]);
								}
							}
						}
					}
				}
			
			} //end
			function comparison(obj2:Object):Boolean
			{
				var a:int;
				a = obj2.a - obj.a;
				a = a < 0 ? a * -1 : a;
				if (a > thresholdObj.a)
					return false;
				
				a = obj2.r - obj.r;
				a = a < 0 ? a * -1 : a;
				if (a > thresholdObj.r)
					return false;
				
				a = obj2.g - obj.g;
				a = a < 0 ? a * -1 : a;
				if (a > thresholdObj.g)
					return false;
				
				a = obj2.b - obj.b;
				a = a < 0 ? a * -1 : a;
				if (a > thresholdObj.b)
					return false;
				
				return true;
			}
		}
		
		/**
		 * 撤销
		 */
		private function revoke():void
		{
			if (arr.length)
			{
				bmd = arr.pop();
				updateBmd();
			}
		}
		var file4save:FileReference = new FileReference();
		
		/**
		 * 保存
		 */
		private function save():void
		{
			if (bmd)
			{
				var bytes:ByteArray;
				bytes = PNGEncoder.encode(bmd);
				file4save.save(bytes, fileName.split(".")[0] + ".png");
			}
		}
		
		/**
		 * 拾取颜色
		 */
		private function pickColor():void
		{
			var p:Point = new Point(stage.mouseX, stage.mouseY);
			p = bmpCon.globalToLocal(p);
			pickedColor = bmd.getPixel32(p.x, p.y);
			updateColor();
		}
		
		/**
		 * 拖动滑块对图片进行缩放
		 * @param	e
		 */
		private function sliderChanged(e:Event):void
		{
			bmpCon.scaleX = bmpCon.scaleY = slider.value;
			panel.update();
		}
		
		/**
		 * 更新拾取的颜色值
		 */
		private function updateColor():void
		{
			var obj:Object = colorResolve(pickedColor);
			tf1.text = pickedColor.toString(16);
			colorCube.graphics.clear();
			colorCube.graphics.lineStyle(0, 0x000000);
			colorCube.graphics.beginFill(obj.c, obj.a / 255);
			colorCube.graphics.drawRect(0, 0, 14, 14);
			colorCube.graphics.endFill();
		}
		
		/**
		 * 颜色值分解
		 * @param	co
		 * @return
		 */
		private function colorResolve(co:uint):Object
		{
			var obj:Object = {};
			obj.a = co >> 24 & 0xff;
			obj.r = co >> 16 & 0xff;
			obj.g = co >> 8 & 0xff;
			obj.b = co & 0xff;
			obj.c = co & 0xffffff;
			return obj;
		}
	}

}

效果如下:

获得 Adobe Flash Player

源码打包下载

« 上一篇下一篇 »

相关文章:

(转)图像之魔棒工具实现  (2015-8-24 9:33:37)

发表评论:

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