BitmapDataの境界線指定による2値化 okoi forked:1favorite:7lines:219license : MIT License modified : 2011-04-06 17:28:55 Embed Tweet // // 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(); // アルファチャンネル } Code Fullscreen Preview Fullscreen romatica siouxcitizen.. motikawa_rgm.. djankey Hiiragi swndfl novita001 loader width map bytes ByteArray readUnsignedInt removeEventListener height addEventListener writeUnsignedInt Security.allowDomain Event.COMPLETE currentTarget Event.ADDED_TO_STAGE position Security.loadPolicyFile Math.min Event push URLRequest sort new page view favorite forked pv269 forked from: BitmapDataの境界線指定に.. John_Blackburne forked:0 favorite:0lines:219 (diff:1)