画像の自由変形の練習。
サンプルはこちら。
写真はうちの猫。可愛い。
以下のサイトを参考にしました。
図付きでとても分かりやすかったです。
とゆーか、ほとんどコピペ状態です。
分割の計算部分がちょっとだけ違うかも。
以下、ソースです。
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;
}
}
}
