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の大きさを、指定の枠の大きさに合わせるサンプル

BitmapDataの大きさを、指定の枠の大きさに合わせるサンプル

この場合は300*300の枠に合わせて拡大・縮小します。
loadImageボタンを押して、いろんな大きさの画像ファイルを読み込んでみてください。

ただし、全体のピクセルが16,777,216ピクセル以下の画像に限ります。
これより大きくなるとエラーが出ます。多分。

drawTrianglesとかは今後の投稿の布石です。多分。

@author Hiiragi
package 
{
	import adobe.utils.CustomActions;
	import flash.display.*;
	import flash.events.*;
	import flash.geom.Matrix;
	import flash.geom.Point;
	import flash.net.FileReference;
	
	import com.bit101.components.PushButton;
	
	/**
	 * BitmapDataの大きさを、指定の枠の大きさに合わせるサンプル
	 * 
	 * この場合は300*300の枠に合わせて拡大・縮小します。
	 * loadImageボタンを押して、いろんな大きさの画像ファイルを読み込んでみてください。
	 * 
	 * ただし、全体のピクセルが16,777,216ピクセル以下の画像に限ります。
	 * これより大きくなるとエラーが出ます。多分。
	 * 
	 * drawTrianglesとかは今後の投稿の布石です。多分。
	 * 
	 * @author Hiiragi
	 */
	[SWF(width = 465, height = 465, frameRate = 30, backgroundColor = 0)]
	public class Main extends Sprite 
	{
		private var _scenes:Vector.<Sprite>;
		
		private var _fr:FileReference;
		private var _loader:Loader;
		
		private var _enemyImage:BitmapData;
		private var _enemyImageMaxWidth:int = 300;
		private var _enemyImageMaxHeight:int = 300;
		
		private var _enemySprite:Sprite;
		private var _attackPoints:Vector.<Point>;
		
		private var _vertices:Vector.<Number>;
		private var _indices:Vector.<int>;
		private var _uvtData:Vector.<Number>;
		
		public function Main():void 
		{
			_fr = new FileReference();
			_scenes = new Vector.<Sprite>;
			_loader = new Loader();
			_enemySprite = new Sprite();
			
			_fr.addEventListener(Event.SELECT, fileSelectedHandler);
			
			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
			
			//枠
			var frame:Sprite = new Sprite();
			frame.graphics.lineStyle(2, 0xFFFFFF);
			frame.graphics.drawRect(0, 0, _enemyImageMaxWidth, _enemyImageMaxHeight);
			frame.x = this.stage.stageWidth / 2 - frame.width / 2;
			frame.y = this.stage.stageHeight / 2 - frame.height / 2;
			this.addChild(frame);
			
			//LoadButton
			var loadBtn:PushButton = new PushButton(this, 0, 0, "load Image", loadBrowse);
		}
		
		private function loadBrowse(e:MouseEvent):void
		{
			_fr.browse();
		}
		
		private function fileSelectedHandler(e:Event):void 
		{
			_fr.addEventListener(ProgressEvent.PROGRESS,onProgress);
			_fr.addEventListener(Event.COMPLETE,onComplete);
			// _fr.addEventListener(Event.OPEN, onOpen);
			// _fr.addEventListener(IOErrorEvent.IO_ERROR, onIoError);
			_fr.load(); // 読み込み処理を開始

		}
		
		private function onProgress(e:ProgressEvent):void
		{
			trace("読み込んだバイト数:" + e.bytesLoaded + "、 全体のバイト数:" + e.bytesTotal);
		}
		
		private function onComplete(e:Event):void
		{
			_loader.contentLoaderInfo.addEventListener(Event.COMPLETE, imgLoadComplete);
			_loader.loadBytes(_fr.data);
			
			// fr.type を参考にオブジェクト変換する等の処理を記述
			// fr.removeEventListener(...)
		}
		
		private function imgLoadComplete(e:Event):void 
		{
			trace("enemyImage Load Completed");
			
			_enemyImage = imageSizeCompressor(Bitmap(_loader.content).bitmapData, _enemyImageMaxWidth, _enemyImageMaxHeight);
			
			drawImage();
			
			_enemySprite.x = this.stage.stageWidth / 2 - _enemySprite.width / 2;
			_enemySprite.y = this.stage.stageHeight / 2 - _enemySprite.height / 2;
			trace("_enemyImage.width = " + _enemyImage.width + " , _enemyImage.height = " + _enemyImage.height);
			trace("_enemySprite.width = " + _enemySprite.width + " , _enemySprite.height = " + _enemySprite.height);
			
			this.addChild(_enemySprite)
		}
		
		/**
		 * 指定のBitmapDataを、幅と高さの比率をそのままに、閾値に合わせて拡大縮小します。
		 * 
		 * @param	inputBitmapData	拡大・縮小したいBitmapData
		 * @param	maxWidth		幅の閾値
		 * @param	maxHeight		高さの閾値
		 * @return	閾値に合わせて拡大・縮小したBitmapData
		 */
		private function imageSizeCompressor(inputBitmapData:BitmapData, maxWidth:int, maxHeight:int):BitmapData
		{
			var ratio:Number;	//どれくらい拡大・縮小するか
			var fixWidth:int;	//拡大・縮小したときの幅
			var fixHeight:int;	//拡大・縮小したときの高さ
			
			var returnBitmapData:BitmapData;
			
			//maxWidth * maxHeightの範囲内に最大限に収める
			//横長の場合
			if (inputBitmapData.width / inputBitmapData.height >=  maxWidth / maxHeight)
			{
				//横長なので、横の大きさを閾値に合わせ、その比率分、高さを拡大縮小して、縦横の比率をそのままにサイズ変更する。
				ratio = _enemyImageMaxWidth / inputBitmapData.width;
				fixWidth = _enemyImageMaxWidth;
				fixHeight = inputBitmapData.height * ratio;
			}
			//縦長の場合
			else if (inputBitmapData.width / inputBitmapData.height <  maxWidth / maxHeight)
			{
				ratio = _enemyImageMaxHeight / inputBitmapData.height;
				fixWidth = inputBitmapData.width * ratio;
				fixHeight = _enemyImageMaxHeight;
			}
			
			returnBitmapData = new BitmapData(fixWidth, fixHeight, true, 0x0);
			returnBitmapData.draw(inputBitmapData, new Matrix(ratio, 0, 0, ratio));
			
			return returnBitmapData;
		}
		
		private function drawImage():void
		{
			_vertices = new Vector.<Number>;
			_indices = new Vector.<int>;
			_uvtData = new Vector.<Number>;
			
			var w:int = _enemyImage.width;
			var h:int = _enemyImage.height;
			
			var xNum:int = 20;
			var yNum:int = 20;
			
			var xDiff:Number = w / (xNum - 1);
			var yDiff:Number = h / (yNum - 1);
			
			for (var y:int = 0; y < yNum; y++)
			{
				for (var x:int = 0; x < xNum; x++)
				{
					_vertices.push(xDiff * x, yDiff * y);
					_uvtData.push(x / (xNum - 1), y / (yNum - 1));
					
					if (x < xNum - 1)
					{
						var pos:int = x + y * xNum;
						_indices.push(pos, pos + 1, pos + xNum, pos + xNum, pos + 1, pos + xNum + 1);
					}
					
				}
			}
			
			var g:Graphics = _enemySprite.graphics;
			g.clear();
			//g.lineStyle(1, 0xFFFFFF);
			g.beginBitmapFill(_enemyImage, null, false, true);
			g.drawTriangles(_vertices, _indices, _uvtData);
			g.endFill();
		}

	}
	
}