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); } } }
效果:
发表评论:
◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。