forked from: Image Transformer
...
@author narutohyper
/**
* Copyright zahir ( http://wonderfl.net/user/zahir )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/3IkT
*/
// forked from narutohyper's Image Transformer
package
{
import flash.geom.Matrix;
import flash.display.Bitmap;
import com.bit101.components.PushButton;
import flash.display.BitmapData;
import flash.display.Loader;
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.text.TextField;
import flash.text.TextFieldAutoSize;
import flash.text.TextFormat;
/**
* ...
* @author narutohyper
*/
[SWF(width = 465, height = 465, frameRate = 60,backgroundColor=0xFFFFFF)]
public class Main extends Sprite {
private var movers:Vector.<Mover> = new Vector.<Mover>(4)
private var mover:Sprite = new Sprite();
private var transformer:Transformer = new Transformer()
private var bmd:BitmapData
private var bt:PushButton
private var label:TextField
private var imgLoader:ImageLoader
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
stage.scaleMode = StageScaleMode.NO_SCALE;
stage.align = StageAlign.TOP_LEFT;
stage.quality = StageQuality.HIGH;
bt = new PushButton(this, 10, 10, "Load Image", imgLoad)
imgLoader = new ImageLoader(this)
//Loadstatus表示
label = new TextField()
label.autoSize = TextFieldAutoSize.LEFT;
label.width = 200
label.height = 40
label.x = 120
label.y = 10
addChild(label);
var format:TextFormat=new TextFormat();
format.font = "_ゴシック";
label.defaultTextFormat=format
label.text="Load Imageで画像読み込み"
//画像の読み込み
//controlPoint
var i:int = 0;
for (i = 0; i < 4; i++) {
movers[i] = new Mover()
movers[i].addEventListener(Mover.MOVE, onVertexMove);
mover.addChild(movers[i]);
}
stage.addEventListener(Event.RESIZE,onResize)
}
private function onResize(e:Event=null):void {
mover.x = (stage.stageWidth - bmd.width)/2;
mover.y = (stage.stageHeight - bmd.height) / 2;
transformer.x = mover.x
transformer.y = mover.y
}
private function imgLoad(e:MouseEvent):void {
imgLoader.loadImage();
}
private function onVertexMove(e:MouseEvent):void
{
e.target.x += e.target.mouseX
e.target.y += e.target.mouseY
draw(e.shiftKey)
e.updateAfterEvent();
}
private function draw(shift:Boolean=false):void {
transformer.draw(bmd,movers,shift)
}
public function setImage(img:Loader):void {
//サンプルテキスト
//BitmapData化
var w:int = img.width;
var h:int = img.height;
var scale:Number = 1;
var bd:BitmapData = ( img.content as Bitmap ).bitmapData;
if( w > h ) scale = 300 / w;
else scale = 300 / h;
w *= scale;
h *= scale;
var m:Matrix = new Matrix();
m.scale(scale,scale);
bmd = new BitmapData(w, h, true, 0x0);
bmd.draw( bd,m,null,null,null,true);
movers[0].x = 0;
movers[0].y = 0;
movers[1].x = bmd.width;
movers[1].y = 0;
movers[2].x = bmd.width;
movers[2].y = bmd.height;
movers[3].x = 0;
movers[3].y = bmd.height;
//Transformer
addChild(transformer);
addChild(mover);
onResize()
draw();
}
public function information(str:String):void {
label.text = str;
}
}
}
import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.display.Loader;
import flash.display.Sprite;
import flash.events.Event;
import flash.events.IOErrorEvent;
import flash.events.MouseEvent;
import flash.geom.Point;
import flash.net.FileFilter;
import flash.net.FileReference;
class Transformer extends Sprite {
public var polygons:Vector.<Polygon>
public var vertices:Vector.<Vertex>
public function Transformer() {
}
public function draw(base:BitmapData, mp:Vector.<Mover>,shift:Boolean=false):void {
//vertexMoversのPointを自分自身でLocal化
var gPoint:Point
var uv:Array=[]
uv[0] = new Point(0, 0);
uv[1] = new Point(1, 0);
uv[2] = new Point(1, 1);
uv[3] = new Point(0, 1);
vertices = new Vector.<Vertex>();
polygons = new Vector.<Polygon>();
//20×20の頂点を用意する
var vCounter:uint = 0
var pCounter:uint = 0
var leftPt:Point
var rightPt:Point
var leftUv:Point
var rightUv:Point
var tempUv:Point
var tempPt:Point
var vy:int
var vx:int
for (vy = 0; vy < 21; vy++) {
//左辺のPoint
//右辺のPoint
//左辺のUv
//右辺のUv
leftPt = Point.interpolate(new Point(mp[1].x, mp[1].y), new Point(mp[2].x, mp[2].y), (1 / 20 * vy));
rightPt = Point.interpolate(new Point(mp[0].x, mp[0].y), new Point(mp[3].x, mp[3].y), (1 / 20 * vy));
leftUv =Point.interpolate(uv[1],uv[2], (1/20*vy));
rightUv=Point.interpolate(uv[0],uv[3], (1/20*vy));
for (vx = 0; vx < 21; vx++) {
tempUv=Point.interpolate(leftUv,rightUv, 1-(1/20*vx));
tempPt=Point.interpolate(leftPt,rightPt, 1-(1/20*vx));
vertices[vCounter] = new Vertex(tempPt.x, tempPt.y, tempUv.x, tempUv.y)
if (vx < 20 && vy < 20) {
polygons[pCounter] = new Polygon(vCounter, vCounter+1, vCounter+22, vCounter+21)
pCounter++
}
vCounter++
}
}
var points:Vector.<Number> = new Vector.<Number>()
var indices:Vector.<int> = new Vector.<int>()
var uvtData:Vector.<Number> = new Vector.<Number>
var count:uint = vertices.length
var i:uint;
for (i = 0; i < count; i++) {
points[i * 2] = vertices[i].x;
points[i * 2 + 1] = vertices[i].y;
uvtData[i * 2] = vertices[i].u;
uvtData[i * 2 + 1] = vertices[i].v;
}
count = polygons.length
for (i = 0; i < count; i++) {
indices=indices.concat(polygons[i].indices)
}
graphics.clear();
if (shift) {
graphics.lineStyle(0,0x009900)
}
graphics.beginBitmapFill(base,null,false,true);
graphics.drawTriangles(points,indices,uvtData)
graphics.endFill();
}
}
class Polygon {
private var _indices:Vector.<uint>
private var _id:uint
public function Polygon(v0:uint,v1:uint,v2:uint,v3:uint) {
_indices = new Vector.<uint>(4)
_indices[0]=v0
_indices[1]=v1
_indices[2]=v2
_indices[3]=v3
}
public function get id():uint {
return _id;
}
public function set id(value:uint):void {
_id = value;
}
public function get indices():Vector.<int> {
var result:Vector.<int> = new Vector.<int>();
result[0] = _indices[0];
result[1] = _indices[1];
result[2] = _indices[2];
result[3] = _indices[0];
result[4] = _indices[2];
result[5] = _indices[3];
return result;
}
}
class Vertex extends Point{
private var _u:Number;
private var _v:Number;
private var _id:uint;
private var _next:Vertex;
public function Vertex(x:Number = 0, y:Number = 0, u:Number = 0, v:Number = 0) {
super(x,y)
_u = u;
_v = v;
}
public function get u():Number { return _u; }
public function set u(value:Number):void {
_u = value;
}
public function get v():Number { return _v; }
public function set v(value:Number):void {
_v = value;
}
}
class Mover extends Sprite {
public static const MOVE:String = 'string';
public function Mover() {
graphics.lineStyle(0, 0xFFFFFF);
graphics.beginFill(0x0000CC)
graphics.drawRect( -5, -5, 10, 10)
graphics.endFill();
addEventListener(MouseEvent.MOUSE_DOWN, mouseDown);
}
private function mouseDown(e:MouseEvent):void {
removeEventListener(MouseEvent.MOUSE_DOWN, mouseDown);
stage.addEventListener(MouseEvent.MOUSE_MOVE, mouseMove);
stage.addEventListener(MouseEvent.MOUSE_UP, mouseUp);
}
private function mouseUp(e:MouseEvent):void {
addEventListener(MouseEvent.MOUSE_DOWN, mouseDown);
stage.removeEventListener(MouseEvent.MOUSE_MOVE, mouseMove);
stage.removeEventListener(MouseEvent.MOUSE_UP, mouseUp);
}
private function mouseMove(e:MouseEvent):void {
dispatchEvent(
new MouseEvent(MOVE,
e.bubbles,
e.cancelable,
e.localX,
e.localY,
e.relatedObject,
e.ctrlKey,
e.altKey,
e.shiftKey,
e.buttonDown,
e.delta));
}
public function destroy():void {
removeEventListener(MouseEvent.MOUSE_DOWN, mouseDown);
stage.removeEventListener(MouseEvent.MOUSE_MOVE, mouseMove);
stage.removeEventListener(MouseEvent.MOUSE_UP, mouseUp);
}
}
/**
* ...
* @author narutohyper
*/
class ImageLoader extends Sprite {
private var _mc:Main
private var _file:FileReference
private var _loader:Loader = new Loader()
public function ImageLoader(mc:Main) {
_mc = mc;
}
// load image
public function loadImage():void {
_file = new FileReference();
_file.addEventListener(Event.SELECT, loadFileSelected);
_file.addEventListener(Event.CANCEL, loadCancel);
var imagesFilter:FileFilter = new FileFilter("Images(jpg,gif,png)", "*.jpg;*.gif;*.png");
_file.browse([imagesFilter]);
}
private function loadCancel(e:Event):void {
_file.removeEventListener(Event.SELECT, loadFileSelected);
_file.removeEventListener(Event.CANCEL, loadCancel);
}
private function loadFileSelected(e:Event):void {
_file.removeEventListener(Event.SELECT, loadFileSelected);
_file.removeEventListener(Event.CANCEL, loadCancel);
_file = FileReference(e.target);
_file.addEventListener(Event.COMPLETE, fileLoaded);
_file.load();
}
private function fileLoaded(e:Event):void {
_file.removeEventListener(Event.COMPLETE, fileLoaded);
if (_loader) {
_loader.unload();
}
_loader = new Loader()
_loader.contentLoaderInfo.addEventListener(IOErrorEvent.IO_ERROR, ioError);
_loader.contentLoaderInfo.addEventListener(Event.COMPLETE, imageLoaded);
_loader.loadBytes(FileReference(e.target).data);
function imageLoaded(e:Event):void {
_loader.contentLoaderInfo.removeEventListener(IOErrorEvent.IO_ERROR, ioError);
_loader.contentLoaderInfo.removeEventListener(Event.COMPLETE, imageLoaded);
_mc.setImage(_loader)
}
function ioError(e:IOErrorEvent):void {
_loader.contentLoaderInfo.removeEventListener(IOErrorEvent.IO_ERROR, ioError);
_loader.contentLoaderInfo.removeEventListener(Event.COMPLETE, imageLoaded);
var str:String = "ファイルの読み込みに失敗しました。\n";
_mc.information(str)
}
}
}