image edge

by lizhi
♥0 | Line 181 | Modified 2011-08-20 19:13:54 | MIT License
play

ActionScript3 source code

/**
 * Copyright lizhi ( http://wonderfl.net/user/lizhi )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/t0kR
 */

package  
{
    import flash.display.Bitmap;
    import flash.display.BitmapData;
    import flash.display.Loader;
    import flash.display.Sprite;
    import flash.events.Event;
    import flash.events.MouseEvent;
    import flash.net.FileReference;
    /**
     * ...
     * @author lizhi http://game-develop.net/
     */
    public class ImageEdge extends Sprite
    {
        private var bmd:BitmapData;
        private var stack:Array;
        private var file:FileReference;
        private var loader:Loader;
        public function ImageEdge() 
        {
            stage.addEventListener(MouseEvent.CLICK, onClick);
        }
        
        private function onClick(e:MouseEvent):void 
        {
            file = new FileReference;
            file.browse();
            file.addEventListener(Event.SELECT, onSelect);
        }
        
        private function onSelect(e:Event):void 
        {
            file.addEventListener(Event.COMPLETE, onLoad);
            file.load();
        }
        
        private function onLoad(e:Event):void 
        {
            loader = new Loader;
            loader.loadBytes(file.data);
            loader.contentLoaderInfo.addEventListener(Event.COMPLETE, onLoad2);
        }
        
        private function onLoad2(e:Event):void 
        {
            bmd = (loader.content as Bitmap).bitmapData;
            exe();
        }
        public function exe():void{
            var w:int = 1;
            var grids:Array = [];
            var numCols:int = bmd.width;
            var numRows:int = bmd.height;
            for (var x:int = 0; x < bmd.width;x++ ) {
                for (var y:int = 0; y < bmd.height;y++ ) {
                    if (bmd.getPixel32(x,y)>>>24>0)
                    {
                        if (grids[y] == null)
                            grids[y] = [];
                        var grid:Grid = new Grid;
                        grids[y][x] = grid;
                    }
                }
            }
            
            
            stack = [];
            var areaId:int = 0;
            for (x = 0; x < numCols; x++)
            {
                for (y = 0; y < numRows; y++)
                {
                    if (grids[y]&&grids[y][x] != null && grids[y][x].areaId == -1)
                    {
                        stack.push([x,y,areaId]);
                        while (stack.length>0) {
                            var pars:Array = stack.pop();
                            grids[pars[1]][pars[0]].areaId = pars[2];
                            if (grids[pars[1]] && grids[pars[1]][pars[0] + 1] && grids[pars[1]][pars[0] + 1].areaId == -1)
                                stack.push([pars[0]+1,pars[1],pars[2]]);
                            if (grids[pars[1]] && grids[pars[1]][pars[0] - 1] && grids[pars[1]][pars[0] - 1].areaId == -1)
                                stack.push([pars[0]-1,pars[1],pars[2]]);
                            if (grids[pars[1] + 1] && grids[pars[1] + 1][pars[0]] && grids[pars[1] + 1][pars[0]].areaId == -1)
                                stack.push([pars[0],pars[1]+1,pars[2]]);
                            if (grids[pars[1] - 1] && grids[pars[1] - 1][pars[0]] && grids[pars[1] - 1][pars[0]].areaId == -1)
                                stack.push([pars[0],pars[1]-1,pars[2]]);
                        }
                        
                        areaId++;
                    }
                    
                }
            }
            trace("find same area grids over");
            
            //find lines
            var lines:Array = [];
            for (x = 0; x < numCols; x++)
            {
                for (y = 0; y < numRows; y++)
                {
                    if (grids[y]&&grids[y][x] != null)
                    {
                        if (lines[grids[y][x].areaId] == null) lines[grids[y][x].areaId] = [];
                        //top
                        if (grids[y-1]==null||grids[y-1][x]==null) {
                            var line:Line = new Line;
                            line.x0 = x;
                            line.y0 = y;
                            line.x1 = x + 1;
                            line.y1 = y;
                            lines[grids[y][x].areaId].push(line);
                        }
                        //right
                        if (grids[y][x + 1] == null) {
                            line = new Line;
                            line.x0 = x+1;
                            line.y0 = y;
                            line.x1 = x + 1;
                            line.y1 = y+1;
                            lines[grids[y][x].areaId].push(line);
                        }
                        //bottom
                        if (grids[y + 1] == null || grids[y + 1][x] == null) {
                            line = new Line;
                            line.x0 = x+1;
                            line.y0 = y+1;
                            line.x1 = x;
                            line.y1 = y+1;
                            lines[grids[y][x].areaId].push(line);
                        }
                        //left
                        if (grids[y][x - 1] == null) {
                            line = new Line;
                            line.x0 = x;
                            line.y0 = y+1;
                            line.x1 = x;
                            line.y1 = y;
                            lines[grids[y][x].areaId].push(line);
                        }
                    }
                    
                }
            }
            trace("find lines over");
            
            //sort lines
            var lines2:Array = [];
            for each(var arr:Array in lines) {
                var arr2:Array = [];
                lines2.push(arr2);
                var startLine:Line = arr[0];
                var currentLine:Line = startLine;
                do {
                    arr2.push(currentLine);
                    var toLines:Array = [];
                    for each(line in arr) {
                        if (line.x0 == currentLine.x1 && line.y0 == currentLine.y1) {
                            toLines.push(line);
                        }
                    }
                    if (toLines.length==1) {
                        currentLine = toLines[0];
                    }else{
                        for each(line in toLines) {
                            if (multiply(currentLine.x0,currentLine.y0,currentLine.x1,currentLine.y1,line.x1,line.y1)>0) {
                                currentLine = line;
                            }
                        }
                    }
                }while (currentLine != startLine)
                if (arr2.length<arr.length) {
                    trace("fds");
                }
            }
            
            //draw
            graphics.clear();
            
            for each(arr in lines2) {
                graphics.lineStyle(3, 0xff0000);
                graphics.beginBitmapFill(bmd);
                graphics.moveTo(arr[0].x0 * w, arr[0].y0 * w);
                for (var i:int = 0; i < arr.length; i++ ) {
                    line = arr[i];
                    graphics.lineTo(line.x1 * w, line.y1 * w);
                }
            }
        }
        
        public function multiply(px1:Number, py1:Number, px2:Number, py2:Number, px3:Number, py3:Number):int {
            return (px1 - px3) * (py2 - py3) - (px2 - px3) * (py1 - py3); 
        }
    }

}

class Grid
{
    public var areaId:int = -1;
}

class Line {
    public var x0:int;
    public var y0:int;
    public var x1:int;
    public var y1:int;
}