In case Flash no longer exists; a copy of this site is included in the Flashpoint archive's "ultimate" collection.

Dead Code Preservation :: Archived AS3 works from wonderfl.net

BitmapDataの境界線指定による2値化

Get Adobe Flash player
by okoi 06 Apr 2011
    Embed
/**
 * Copyright okoi ( http://wonderfl.net/user/okoi )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/nuUQ
 */

//
//    BitmapData画像のある色を境界にして2値化する処理
//    今回は白色と透明で区切りたかったためByteArrayとSetPixelsを利用してpaletteMapと同じような処理を再現している
//    スライダーを動かすと境界の位置を変更
//    CheckBoxをクリックすると paletteMapモードとByteArrayモードの切り替えが可能
//
//    ※画像が読み込まれるまでしばらくお待ちください
//
package 
{
    import flash.display.Sprite;
    import flash.events.Event;
    import flash.events.MouseEvent;
    import flash.display.Shape;
    import flash.display.Bitmap;
    import flash.display.BitmapData;
    import flash.geom.Point;
    import flash.system.Security;
    import flash.geom.Matrix;
    import flash.utils.ByteArray;
    
    import com.bit101.components.HSlider;
    import com.bit101.components.Label;
    import com.bit101.components.CheckBox;
    
    [SWF(width = "465", height = "465", frameRate="60")]
    
    /**
     * ...
     * @author 
     */
    public class Main extends Sprite 
    {
        public static const WIDTH:int = 465;
        public static const HEIGHT:int = 465;
        
        private var imagewaku:Shape;
        
        private var image:Image;
        private var canvas:BitmapData = null;
        private var bmp:Bitmap;
        
        private var step:Number;
        
        private var slider:HSlider;
        private var label:Label;
        private var check:CheckBox;
                
        public function Main():void 
        {
            if (stage) init();
            else addEventListener(Event.ADDED_TO_STAGE, init);
        }
        
        private function init(e:Event = null):void 
        {
            removeEventListener(Event.ADDED_TO_STAGE, init);
            // entry point
            graphics.beginFill(0xa9a9a9);
            graphics.drawRect(0, 0, WIDTH, HEIGHT);
            graphics.endFill();
            for ( var y:int = 0; y < 5; y++ )
            {
                for ( var x:int = 0; x < 5; x++ )
                {
                    if ( (5 * y + x) % 2 != 0 )    continue;
                    graphics.beginFill(0xc0c0c0);
                    graphics.drawRect(x * (WIDTH / 5), y * (HEIGHT / 5), (WIDTH / 5), (HEIGHT / 5));
                    graphics.endFill();
                }
            }
            
            Security.allowDomain("assets.wonderfl.net");
            Security.loadPolicyFile("http://assets.wonderfl.net/crossdomain.xml");
       
            image = new Image("http://assets.wonderfl.net/images/related_images/6/6d/6dff/6dff50d5157b019ea6c42bb4b046a7419557277d", CreateCanvas );
              
            imagewaku = new Shape();
            addChild( imagewaku );
            
            bmp = new Bitmap();
            addChild( bmp );
            
            step = 0;
            
            //    スライダー
            slider = new HSlider( this, 0, 0, MoveSliderHandler );
            slider.width = 300;
            slider.height = 20;
            slider.x = 25;
            slider.y = HEIGHT - 80;
            slider.setSliderParams( 0, 256, 0 );
            
            //    ラベル
            label = new Label( this, 0, 0, slider.value + "" );
            label.autoSize = true;
            label.scaleX = 2;
            label.scaleY = 2;
            label.x = 335;
            label.y = HEIGHT - 90;
            
            //    チェックボックス
            check = new CheckBox(this, 0, 0, "ByteArrayMode", CheckBoxHandler);
            check.scaleX = 2;
            check.scaleY = 2;
            check.x = 25;
            check.y = HEIGHT - 40;
        }
        
    
        private function MoveSliderHandler( e:Event ) : void
        {
            if ( e.currentTarget != null && label != null )
            {
                label.text = e.currentTarget.value + "";
                
                if ( check.selected )    DrawImage2();
                else                     DrawImage();
            }
        }
        
        private function CheckBoxHandler( e:Event ) : void
        {
            if ( check.selected )    DrawImage2();
            else                     DrawImage();            
        }
        

        private function CreateCanvas() : void
        {
            canvas = new BitmapData( image.image.width, image.image.height, true, 0 );
            bmp.bitmapData = canvas;
            bmp.x = WIDTH / 2 - canvas.width / 2;
            bmp.y = HEIGHT / 2 - canvas.height / 2 - 40;
                
            imagewaku.graphics.lineStyle(1);
            imagewaku.graphics.drawRect(bmp.x, bmp.y, canvas.width+1, canvas.height+1);
            imagewaku.graphics.endFill();
            
            if ( check.selected )    DrawImage2();
            else                     DrawImage();
        }
        
        /**
         * 現在のスライダーの値からパレットマップを作成する
         * 白色と透明で分断する
         * @return
         */
        private function CreatePaletteMap() : PaletteMapColorData
        {
            var map:PaletteMapColorData = new PaletteMapColorData();
            
            for ( var i:int = 0; i < 256; i++ )
            {
                if ( i >= slider.value )
                {
                    map.r.push( 255 << 24 | 0xFF << 16 | 0xFF << 8 | 0xFF );
                    map.g.push( 255 << 24 | 0xFF << 16 | 0xFF << 8 | 0xFF );
                    map.b.push( 255 << 24 | 0xFF << 16 | 0xFF << 8 | 0xFF );
                    map.a.push( 255 << 24 | 0 | 0 | 0 );
                }else
                {
                    map.r.push( 0 | 0 | 0 | 0 );
                    map.g.push( 0 | 0 | 0 | 0 );
                    map.b.push( 0 | 0 | 0 | 0 );
                    map.a.push( 0 | 0 | 0 | 0 );
                }
            }
            return    map;
        }
        
        
        /**
         * 現在のスライダーの値から絵を変換して描画する
         */
        private function DrawImage() : void
        {
            if ( image.image == null || canvas == null )    return;
                
            canvas.lock();
            canvas.fillRect( canvas.rect, 0 );
                
            var map:PaletteMapColorData = CreatePaletteMap();
            canvas.paletteMap( image.image, canvas.rect, new Point(), map.r, map.g, map.b, map.a );
            canvas.unlock();    
            
        }
        
        /**
         * 現在のスライダーの値からByteArrayを使ってpaletteMapと同等の処理を行う
         */
        private function DrawImage2() : void
        {
            if ( image.image == null || canvas == null )    return;
            
            var bytes:ByteArray;
            var newbytes:ByteArray = new ByteArray();
            
            canvas.lock();
            canvas.fillRect( canvas.rect, 0 );
            canvas.draw( image.image );
            
            bytes = canvas.getPixels( canvas.rect );
            var map:PaletteMapColorData = CreatePaletteMap();
            var pixelnum:uint = bytes.length / 4;
                        
            bytes.position = 0;
            for ( var p:uint = 0; p < pixelnum; p++ )
            {
                var color:uint = bytes.readUnsignedInt();
                var a:uint = (color >> 24) & 0xFF;
                var r:uint = (color >> 16) & 0xFF;
                var g:uint = (color >> 8) & 0xFF;
                var b:uint = (color) & 0xFF;
                
                var alpha:uint = map.a[int((r+g+b)/3)];        //    今回は透明と白で分割したいのでこう表現
                var red:uint = map.r[r];
                var green:uint = map.g[g];
                var blue:uint = map.b[b];
                                
                a = (((alpha >> 24) & 0xFF) + ((red >> 24) & 0xFF) + ((green >> 24) & 0xFF) + ((blue >> 24) & 0xFF)) % 256;
                r = (((alpha >> 16) & 0xFF) + ((red >> 16) & 0xFF) + ((green >> 16) & 0xFF) + ((blue >> 16) & 0xFF)) % 256;
                g = (((alpha >>  8) & 0xFF) + ((red >>  8) & 0xFF) + ((green >>  8) & 0xFF) + ((blue >>  8) & 0xFF)) % 256;
                b = (((alpha >>  0) & 0xFF) + ((red >>  0) & 0xFF) + ((green >>  0) & 0xFF) + ((blue >>  0) & 0xFF)) % 256;
                color = (a << 24) | (r << 16) | (g << 8) | b;

                newbytes.writeUnsignedInt( color );
            }
            
            newbytes.position = 0;
            canvas.setPixels( canvas.rect, newbytes );
            canvas.unlock();
        }
        
    }
}

    import flash.display.BitmapData;
    import flash.display.Bitmap;
    import flash.display.Sprite;
    
    import flash.display.Loader;
    import flash.display.LoaderInfo;
    import flash.net.URLRequest;
    
    import flash.events.Event;
    
    import flash.geom.Matrix;
    import flash.geom.Point;
    
    /**
     * イメージ格納クラス
     * @author 
     */
    class Image
    {
        public static const MAX_W:int = 400;    //    基本サイズ
        public static const MAX_H:int = 300;    //    基本サイズ
        
        public var width:Number = MAX_W;
        public var height:Number = MAX_H;
                
        public    var view:Sprite;
        protected var baseimg:BitmapData;            //元画像データ
        
        private var loader:Loader = null;
        private var loaderinfo:LoaderInfo = null;
        
        private var _loadcallback:Function;
        
        public function Image( path:String, loadcallback:Function = null ) 
        {
             view = new Sprite();
             
             loader = new Loader();
             loaderinfo = loader.contentLoaderInfo;
             loaderinfo.addEventListener( Event.COMPLETE, LoadedImageHandler );             
             loader.load( new URLRequest( path ) );
             
             _loadcallback = loadcallback;
        }
        
        protected function LoadedImageHandler( e:Event ) : void
        {
            loaderinfo.removeEventListener( Event.COMPLETE, LoadedImageHandler );
            
            var scaleX:Number = Math.min( width / loader.width, 1 );
            var scaleY:Number = Math.min( height / loader.height, 1 );
            var scale:Number = ( scaleX < scaleY ) ? scaleX : scaleY;

            width = loader.width * scale;
            height = loader.height * scale;
            
            baseimg = new BitmapData( width, height, true, 0 );
            baseimg.draw( loader, new Matrix(scale, 0, 0, scale, 0, 0) );
            
            loaderinfo = null;
            loader = null;
            
            if ( _loadcallback != null )    _loadcallback();
        }
        
        public function get image():BitmapData { return    baseimg;    }
    }

    /**
     * ...
     * @author 
     */
    class PaletteMapColorData
    {
        public var r:Array = new Array();    //    赤チャンネル
        public var g:Array = new Array();    //    緑チャンネル
        public var b:Array = new Array();    //    青チャンネル
        public var a:Array = new Array();    //    アルファチャンネル        
    }