// forked from Hakuhin's ミップマップでビットマップの縮小 // ------------------------------------------------- // // ミップマップでビットマップの縮小 // // // 画像は大阪市交通局から勝手にお借りしてます。 // // 100%より小さく、少しずつ姿勢を変化させ続けたときに // ビットマップがどのように描画されるかを確認するテストです。 // // マウスホイール回転で拡大縮小が可能です。 // // ------------------------------------------------- package { import flash.events.*; import flash.display.*; import flash.net.*; import flash.text.*; import flash.utils.*; import flash.system.*; import flash.geom.*; import flash.filters.*; import flash.ui.*; import flash.media.*; public class Main extends Sprite { public function Main() { // ------------------------------------------------- // コンストラクタ // ------------------------------------------------- // フレームレート stage.frameRate = 60; // 100%表示 stage.scaleMode = StageScaleMode.NO_SCALE; // 左上 stage.align = StageAlign.TOP_LEFT; stage.align = "TL"; // スプライトを作成 var sprite:Sprite = new Sprite(); var g:Graphics = sprite.graphics; addChild(sprite); // 初期化へ init(); // ------------------------------------------------- // 初期化 // ------------------------------------------------- function init():void{ // 画像のURL var url:String = "http://www.kotsu.city.osaka.jp/ct/image000000500/subway_number.gif"; // ステージサイズ var w:uint; var h:uint; var bmp_src:BitmapData = null; // ローダー作成 var loader_obj : Loader = new Loader(); var info : LoaderInfo = loader_obj.contentLoaderInfo; // 読み込み完了 info.addEventListener (Event.INIT,LoaderInfoInitFunc); function LoaderInfoInitFunc (event : Event):void { // メモリからインスタンス化 var loader_memory : Loader = new Loader(); loader_memory.contentLoaderInfo.addEventListener (Event.COMPLETE,LoaderInfoCompleteFunc); function LoaderInfoCompleteFunc (event : Event):void { var sprite:Sprite = new Sprite(); stage.addChild(sprite); // キャプチャ bmp_src = new BitmapData(loader_memory.width,loader_memory.height,true,0); sprite.addChild(loader_memory); bmp_src.draw(sprite); sprite.removeChild(loader_memory); stage.removeChild(sprite); // リサイズ ResizeFunc(null); } // 読み込み開始 loader_memory.loadBytes(loader_obj.contentLoaderInfo.bytes); } // 読み込み開始 load(url); // リザルト作成 var result : Sprite = new Sprite(); addChild(result); result.x = 0; // ボタン作成 var button:Button = new Button(stage); button.y = 70; button.setSize(60,20); button.setLabel("開く"); result.addChild(button); // ボタンが押された button.addEventListener(MouseEvent.CLICK,function(e:MouseEvent):void{ load(text.text); }); function load(url:String):void{ // 読み込み loader_obj.load(new URLRequest(url)); } // ミップマップ用ラジオボタン var radio_off:RadioButton = new RadioButton(stage); result.addChild(radio_off); radio_off.setLabel("ミップマップなし"); radio_off.x = 0; radio_off.y = 4; radio_off.setSize(120,18); radio_off.onClick(function(obj:RadioButton):void{mipmap = false;}); var radio_on:RadioButton = new RadioButton(stage); result.addChild(radio_on); radio_on.setLabel("ミップマップあり"); radio_on.x = 0; radio_on.y = 22; radio_on.setSize(120,18); radio_on.onClick(function(obj:RadioButton):void{mipmap = true;}); // ラジオボタンを関連付け radio_on.attachGroup(radio_off); radio_on.select(); // 画質用ラジオボタン var radio_low:RadioButton = new RadioButton(stage); result.addChild(radio_low); radio_low.setLabel("画質:low"); radio_low.x = 0; radio_low.y = 4; radio_low.setSize(100,18); radio_low.onClick(function(obj:RadioButton):void{stage.quality = StageQuality.LOW;}); var radio_high:RadioButton = new RadioButton(stage); result.addChild(radio_high); radio_high.setLabel("画質:high"); radio_high.x = 0; radio_high.y = 22; radio_high.setSize(100,18); radio_high.onClick(function(obj:RadioButton):void{stage.quality = StageQuality.HIGH;}); var radio_best:RadioButton = new RadioButton(stage); result.addChild(radio_best); radio_best.setLabel("画質:best"); radio_best.x = 0; radio_best.y = 40; radio_best.setSize(100,18); radio_best.onClick(function(obj:RadioButton):void{stage.quality = StageQuality.BEST;}); // ラジオボタンを関連付け radio_low.attachGroup(radio_high); radio_low.attachGroup(radio_best); radio_high.select(); // テキストフィールド作成 var ft_result:TextField = new TextField(); ft_result.x = 10; ft_result.y = 50; ft_result.width = 300; ft_result.height = 20; ft_result.selectable = false; // 書式 var format_result:TextFormat = new TextFormat(); format_result.font = "MS ゴシック"; // フォント名 ft_result.defaultTextFormat = format_result; // テキスト表示 result.addChild(ft_result); // 読み込み状況 addEventListener (Event.ENTER_FRAME,EnterFrameFunc); function EnterFrameFunc (event : Event) :void{ ft_result.text = "読込:" + info.bytesLoaded + " / 全体:" + info.bytesTotal; } // テキストフィールド作成 var text:TextField = new TextField(); text.x = 10; text.y = 70; text.height = 20; text.type = TextFieldType.INPUT; text.border = true; // 書式 var format:TextFormat = new TextFormat(); format.font = "MS ゴシック"; // フォント名 text.defaultTextFormat = format; // テキスト表示 text.text = url; result.addChild(text); // リサイズ時にフィット stage.addEventListener(Event.RESIZE,ResizeFunc); function ResizeFunc(e:Event):void{ w = stage.stageWidth; h = stage.stageHeight; loader_obj.width = w; loader_obj.height = h - 100; result.y = h - 100; // テキストフィールド位置 text.width = w - 10 - 10 - button.width - 10; // ボタン位置 button.x = w - button.width - 10; // ラジオボタン位置 radio_off.x = w - 270; radio_on.x = w - 270; radio_low.x = w - 100; radio_high.x = w - 100; radio_best.x = w - 100; } ResizeFunc(null); var px:Number = 0; var py:Number = 0; var rot:Number = 0; var sx:Number = 0; var sy:Number = 0; var scale:Number = 0.25; var phase:Number = 0; var mipmap:Boolean = true; var m:Matrix; addEventListener(Event.ENTER_FRAME,function(e:Event):void{ if(!bmp_src) return; // 少し移動 px += 0.1; py += 0.1; // 少し回転 rot += 0.05; // 拡大縮小 phase += 3.0 * Math.PI / 180; sx = Math.cos(phase) * 0.015625 + 1.0; sy = Math.sin(phase) * 0.015625 + 1.0; sx *= scale; sy *= scale; if(mipmap){ var dx:Number = MipmapGetScale(sx); var dy:Number = MipmapGetScale(sy); var bmp_w:uint = Math.floor(dx * bmp_src.width); var bmp_h:uint = Math.floor(dy * bmp_src.height); var bmp_cpy:BitmapData = new BitmapData(bmp_w,bmp_h,true); var q : String = stage.quality; stage.quality = StageQuality.BEST; bmp_cpy.draw( bmp_src, new Matrix(dx,0,0,dy,0,0), new ColorTransform(1,1,1,1,0,0,0,0), BlendMode.NORMAL, new Rectangle(0,0,bmp_w,bmp_h), true ); stage.quality = q; m = new Matrix(); m.identity(); m.scale(1.0/dx,1.0/dy); m.translate(px,py); m.translate(-w/2.0,-(h-100)/2.0); m.scale(sx , sy); m.rotate(rot * Math.PI / 180); m.translate( w/2.0, (h-100)/2.0); g.clear(); g.beginBitmapFill(bmp_cpy,m,true,true); g.drawRect(0,0,w,h-100); g.endFill(); }else{ m = new Matrix(); m.identity(); m.translate(px,py); m.translate(-w/2.0,-(h-100)/2.0); m.scale(sx , sy); m.rotate(rot * Math.PI / 180); m.translate( w/2.0, (h-100)/2.0); g.clear(); g.beginBitmapFill(bmp_src,m,true,true); g.drawRect(0,0,w,h-100); g.endFill(); } }); function MipmapGetScale(d:Number):Number{ if(d <= 0.0) return 1.0; var i:Number = 1.0; while(true){ i /= 2.0; if(d > i) break; } return i * 2.0; } // テキスト表示 var tf : TextField = new TextField(); tf.x = 5; tf.y = 5; tf.width = 150; tf.height = 34; tf.border = true; tf.background = true; tf.alpha = 0.9; // 書式 format = new TextFormat(); format.font = "MS ゴシック"; tf.defaultTextFormat = format; addChild(tf); addEventListener(Event.ENTER_FRAME,function(e:Event):void{ var str:String = ""; var d:Number; str += "scaleX : " + Math.floor(sx * 100000) / 100000 + "\n"; str += "scaleY : " + Math.floor(sy * 100000) / 100000 + "\n"; tf.text = str; }); // マウス操作 addEventListener(MouseEvent.MOUSE_WHEEL, function (event:MouseEvent):void{ scale += event.delta * 0.01; if(scale < 0.02) scale = 0.02; if(scale > 1.00) scale = 1.00; }); } } } } import flash.events.*; import flash.display.*; import flash.text.*; import flash.geom.*; // ------------------------------------------------- // ボタン // ------------------------------------------------- internal class Button extends Sprite { private var _width:Number; private var _height:Number; private var _text:TextField; private var _background:Sprite; public function Button(stage:Stage) { var slider:Button = this; // 背景用スプライト作成 _background = new Sprite(); addChild(_background); // テキストフィールド _text = new TextField(); addChild(_text); _text.x = 0; _text.y = 0; _text.selectable = false; // 書式 var format:TextFormat = new TextFormat(); format.align = TextFormatAlign.CENTER; // 整列 format.font = "MS ゴシック"; // フォント名 format.size = 14; // 文字のポイントサイズ format.color = 0x202020; // 文字の色 _text.defaultTextFormat = format; // マウスオーバーで少し明るく addEventListener(MouseEvent.MOUSE_OVER,function(e:MouseEvent):void{ var color : ColorTransform = new ColorTransform(1,1,1,1,8,8,8,0); transform.colorTransform = color; }); // マウスアウトで元に戻す addEventListener(MouseEvent.MOUSE_OUT,function(e:MouseEvent):void{ var color : ColorTransform = new ColorTransform(1,1,1,1,0,0,0,0); transform.colorTransform = color; }); // デフォルト値 setSize(100,100); update(); } // リサイズ public function setSize(w:Number,h:Number):void{ // 背景リサイズ _width = w; _height = h; update(); } // ラベルセット public function setLabel(str:String):void{ _text.text = str; update(); } // 描画更新 private function update():void{ // 背景描画 var g:Graphics = _background.graphics; // 角丸矩形描画 g.clear(); g.lineStyle ( 0 , 0x808080 , 1.0,false,LineScaleMode.NONE,CapsStyle.ROUND,JointStyle.ROUND); g.beginFill ( 0xF0F0F0 , 1.0 ); g.drawRoundRect ( 0 , 0 , _width , _height , 5 , 5 ); g.endFill(); // テキスト位置修正 _text.width = _width; _text.height = _height; } } import flash.events.*; import flash.display.*; import flash.text.*; import flash.geom.*; // ------------------------------------------------- // ラジオボタン // ------------------------------------------------- internal class RadioButton extends Sprite { private var _width:Number; private var _height:Number; private var _text:TextField; private var _background:Sprite; private var _button:Sprite; private var _check:Sprite; private var _pref:RadioButton; private var _post:RadioButton; private var _selected:Boolean; private var _onClick:Function; public function RadioButton(stage:Stage) { var slider:RadioButton = this; _onClick = null; _selected = false; // リングリスト作成 _pref = this; _post = this; // 背景用スプライト作成 _background = new Sprite(); addChild(_background); // ボタン用スプライト作成 _button = new Sprite(); addChild(_button); // チェック用スプライト作成 _check = new Sprite(); addChild(_check); // テキストフィールド _text = new TextField(); addChild(_text); _text.x = 20; _text.y = 0; _text.selectable = false; // 書式 var format:TextFormat = new TextFormat(); format.align = TextFormatAlign.LEFT; // 整列 format.font = "MS ゴシック"; // フォント名 format.size = 14; // 文字のポイントサイズ format.color = 0x202020; // 文字の色 _text.defaultTextFormat = format; // マウスオーバーで少し明るく addEventListener(MouseEvent.MOUSE_OVER,function(e:MouseEvent):void{ var color : ColorTransform = new ColorTransform(1,1,1,1,8,8,8,0); transform.colorTransform = color; }); // マウスアウトで元に戻す addEventListener(MouseEvent.MOUSE_OUT,function(e:MouseEvent):void{ var color : ColorTransform = new ColorTransform(1,1,1,1,0,0,0,0); transform.colorTransform = color; }); // クリック addEventListener(MouseEvent.CLICK,function(e:MouseEvent):void{ select(); }); // デフォルト値 setSize(100,100); update(); } // リサイズ public function setSize(w:Number,h:Number):void{ // 背景リサイズ _width = w; _height = h; update(); } // ラベルセット public function setLabel(str:String):void{ _text.text = str; update(); } // 描画更新 private function update():void{ // 背景描画 var g:Graphics; var height_half:Number = _height / 2; var r:Number; // 背景描画 g = _background.graphics; g.clear(); g.beginFill ( 0xFFFFFF , 0.0 ); g.drawRect ( 0 , 0 , _width , _height ); g.endFill(); // ボタン描画 g = _button.graphics; g.clear(); g.lineStyle ( 0 , 0x808080 , 1.0,false,LineScaleMode.NONE,CapsStyle.ROUND,JointStyle.ROUND); g.beginFill ( 0xF0F0F0 , 1.0 ); r = height_half - 4; if(r < 4) r = 4; g.drawCircle ( height_half , height_half , r ); g.endFill(); // 背景描画 g = _check.graphics; g.clear(); g.lineStyle ( 0 , 0x404040 , 1.0,false,LineScaleMode.NONE,CapsStyle.ROUND,JointStyle.ROUND); g.beginFill ( 0x606060 , 1.0 ); r = height_half - 8; if(r < 2) r = 2; g.drawCircle ( height_half , height_half , r ); g.endFill(); // テキスト位置修正 _text.x = _height; _text.width = _width; _text.height = _height; if(_selected) _check.visible = true; else _check.visible = false; } // グループにセット public function attachGroup(button:RadioButton):void{ button.removeGroup(); var pref:RadioButton = this; var post:RadioButton = _post; pref._post = button; post._pref = button; button._pref = pref; button._post = post; } // グループから外す public function removeGroup():void{ var pref:RadioButton = _pref; var post:RadioButton = _post; pref._post = post; post._pref = pref; _pref = this; _post = this; } // 選択 public function select():void{ // すべてのチェックを外す var list:RadioButton = this._post; while(true){ if(list == this) break; list._selected = false; list.update(); list = list._post; } // チェック list._selected = true; list.update(); // コールバック関数呼び出し if(_onClick != null){ _onClick(this); } } // イベント登録 public function onClick(func:Function):void{ _onClick = func; } } // ------------------------------------------------- // 外部画像をサムネイルとしてキャプチャ // ------------------------------------------------- import flash.net.*; import flash.events.*; import flash.display.*; import flash.geom.*; function ThumbnailCapture(url:String,time:uint,stage:Stage):void{ // キャプチャタイミング Wonderfl.capture_delay( time ); // スプライト作成 var sprite : Sprite = new Sprite(); // ステージ最前面に配置 stage.addChildAt(sprite,stage.numChildren); // ローダー var loader_obj : Loader = new Loader(); loader_obj.contentLoaderInfo.addEventListener (Event.INIT,function(e:Event):void{ // メモリからインスタンス化 var loader_memory : Loader = new Loader(); loader_memory.contentLoaderInfo.addEventListener (Event.INIT,function(e:Event):void{ // キャプチャ var bmp : BitmapData = new BitmapData(loader_memory.width,loader_memory.height,true,0); sprite.addChild(loader_memory); bmp.draw(sprite); sprite.removeChild(loader_memory); loader_memory.unload(); loader_obj.unload(); loader_memory = null; loader_obj = null; // 画像を配置 var bmp_obj : Bitmap = new Bitmap(bmp); bmp_obj .width = stage.stageWidth; bmp_obj .height = stage.stageHeight; stage.addChild(bmp_obj ); }); // 読み込み開始 loader_memory.loadBytes(loader_obj.contentLoaderInfo.bytes); }); // 読み込み開始 loader_obj.load(new URLRequest(url)); } forked from: ミップマップでビットマップの縮小