AS3で画像の自由変形

Filed under AS3



画像の自由変形の練習。

サンプルはこちら

写真はうちの猫。可愛い。

以下のサイトを参考にしました。

四角形の自由変形

図付きでとても分かりやすかったです。

とゆーか、ほとんどコピペ状態です。

分割の計算部分がちょっとだけ違うかも。

以下、ソースです。

package
{
	import flash.display.Bitmap;
	import flash.display.BitmapData;
	import flash.display.Graphics;
	import flash.display.Sprite;
	import flash.display.StageAlign;
	import flash.display.StageQuality;
	import flash.display.StageScaleMode;
	import flash.events.Event;
	import flash.events.MouseEvent;
	import flash.geom.Matrix;
	import flash.geom.Point;

	public class Image_transform3 extends Sprite
	{
		// 分割数
		private static const hDiv:int=5;
		private static const vDiv:int=5;
		private var showLine:Boolean;

		// 画像
		[Embed(source='image.jpg')]
		private var img:Class;
		private var bmpd:BitmapData;
		private var w:Number;
		private var h:Number;

		// 動かす点を4つ
		private var point0:Sprite;
		private var point1:Sprite;
		private var point2:Sprite;
		private var point3:Sprite;

		public function Image_transform3()
		{
			// ステージの設定
			stage.scaleMode=StageScaleMode.NO_SCALE;
			stage.align=StageAlign.TOP_LEFT;
			stage.quality=StageQuality.HIGH;
			stage.frameRate=40;

			// 画像の用意
			bmpd=(new img as Bitmap).bitmapData;
			w=bmpd.width;
			h=bmpd.height;
			showLine=false;

			// 動かす点の用意 (左上、 右上、 左下、 右下)
			point0=createCircle(50, 50);
			point1=createCircle(50 + w, 50);
			point2=createCircle(50, 50 + h);
			point3=createCircle(50 + w, 50 + h);

			addEventListener(Event.ENTER_FRAME, onFrame);
			stage.addEventListener(MouseEvent.CLICK, function():void
			{
				showLine=(showLine) ? (false) : (true);
			});
		}

		// 画像を描写する関数
		private function onFrame(e:Event):void
		{
			graphics.clear();

			// 描写
			// こちらを参考にしました。:http://www.d-project.com/flex/009_FreeTransform/
			var a0:Point=new Point;
			var a1:Point=new Point(w, 0);
			var a2:Point=new Point(0, h);
			var a3:Point=new Point(w, h);

			var b0:Point=new Point(point0.x, point0.y);
			var b1:Point=new Point(point1.x, point1.y);
			var b2:Point=new Point(point2.x, point2.y);
			var b3:Point=new Point(point3.x, point3.y);

			for(var i:int=0; i < hDiv; i++)
			{
				var h0:Number=i / hDiv;
				var h1:Number=(i + 1) / hDiv;

				var ta0:Point=getPoint(a0, a1, h0);
				var ta1:Point=getPoint(a0, a1, h1);
				var ta2:Point=getPoint(a2, a3, h0);
				var ta3:Point=getPoint(a2, a3, h1);

				var tb0:Point=getPoint(b0, b1, h0);
				var tb1:Point=getPoint(b0, b1, h1);
				var tb2:Point=getPoint(b2, b3, h0);
				var tb3:Point=getPoint(b2, b3, h1);

				for(var j:int=0; j < vDiv; j++)
				{
					var v0:Number=j / vDiv;
					var v1:Number=(j + 1) / vDiv;

					var tta0:Point=getPoint(ta0, ta2, v0);
					var tta1:Point=getPoint(ta0, ta2, v1);
					var tta2:Point=getPoint(ta1, ta3, v0);
					var tta3:Point=getPoint(ta1, ta3, v1);

					var ttb0:Point=getPoint(tb0, tb2, v0);
					var ttb1:Point=getPoint(tb0, tb2, v1);
					var ttb2:Point=getPoint(tb1, tb3, v0);
					var ttb3:Point=getPoint(tb1, tb3, v1);

					var mtx:Matrix=createMatrix(tta0, tta1, tta2, ttb0, ttb1, ttb2);
					graphics.beginBitmapFill(bmpd, mtx);
					if (showLine)  graphics.lineStyle(2, 0x00ff00);
					graphics.moveTo(ttb0.x, ttb0.y);
					graphics.lineTo(ttb1.x, ttb1.y);
					graphics.lineTo(ttb2.x, ttb2.y);
					graphics.endFill();

					mtx=createMatrix(tta3, tta1, tta2, ttb3, ttb1, ttb2);
					graphics.beginBitmapFill(bmpd, mtx);
					if (showLine) graphics.lineStyle(2, 0x00ff00);
					graphics.moveTo(ttb3.x, ttb3.y);
					graphics.lineTo(ttb1.x, ttb1.y);
					graphics.lineTo(ttb2.x, ttb2.y);
					graphics.endFill();
				}
			}
		}

		// 分割点計算用関数
		// こちらのものを使わせてもらいました。:http://www.d-project.com/flex/009_FreeTransform/
		private function getPoint(p0:Point, p1:Point, ratio:Number):Point
		{
			return new Point(p0.x + (p1.x - p0.x) * ratio, p0.y + (p1.y - p0.y) * ratio);
		}

		// 変形用行列の作成用関数
		// こちらのものを使わせてもらいました。:http://www.d-project.com/flex/009_FreeTransform/
		private function createMatrix(a0:Point, a1:Point, a2:Point, point0:Point, point1:Point, point2:Point):Matrix
		{
			var ma:Matrix=new Matrix(a1.x - a0.x, a1.y - a0.y, a2.x - a0.x, a2.y - a0.y);
			var mb:Matrix=new Matrix(point1.x - point0.x, point1.y - point0.y, point2.x - point0.x, point2.y - point0.y);
			ma.invert();

			var m:Matrix=new Matrix();
			m.translate(-a0.x, -a0.y);
			m.concat(ma);
			m.concat(mb);
			m.translate(point0.x, point0.y);

			return m;
		}

		// 円を作る関数
		private function createCircle(x:Number, y:Number):Sprite
		{
			var sp:Sprite=addChild(new Sprite)as Sprite;
			sp.addEventListener(MouseEvent.MOUSE_DOWN, function():void{sp.startDrag()});
			sp.addEventListener(MouseEvent.MOUSE_UP, function():void{sp.stopDrag()});
			sp.x=x;
			sp.y=y;

			var g:Graphics=sp.graphics;
			g.beginFill(0x0000ff, 1);
			g.drawCircle(0, 0, 10);
			g.endFill();

			return sp;
		}
	}
}

Post a Comment

Your email is never published nor shared.