画像を切り抜く範囲(とりあえず保存できる)
画像を切り抜いて保存できるようにした
画像もローカルからアップロードできるけど,
サイズ調整していないので465x465じゃないと使い物にならない.
フルスクリーンならなんとかなるかな?
/**
* Copyright geko ( http://wonderfl.net/user/geko )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/8oOn
*/
//画像を切り抜いて保存できるようにした
//画像もローカルからアップロードできるけど,
//サイズ調整していないので465x465じゃないと使い物にならない.
//フルスクリーンならなんとかなるかな?
package {
import flash.geom.Matrix;
import flash.utils.ByteArray;
import flash.geom.Point;
import flash.display.BitmapData;
import flash.display.DisplayObjectContainer;
import flash.display.Loader;
import flash.display.Sprite;
import flash.display.Stage;
import flash.display.StageAlign;
import flash.display.StageScaleMode;
import flash.events.*;
import flash.net.FileFilter;
import flash.net.FileReference;
import flash.net.URLRequest;
import flash.system.LoaderContext;
import com.adobe.images.*;
[SWF(backgroundColor=0x555555)]
public class FlashTest extends Sprite {
private static var PIG_IMAGE:String = "http://assets.wonderfl.net/images/related_images/d/d3/d3b4/d3b433219e53b955f0e99b4cdb8f80cc2f1635f8";
private var sf:ScrapField;
private var canvas:Sprite;
private var loader:Loader;
private var menuBar:MenuBar;
private var fanLoader:FanLoader;
private var loaderContent:Sprite;
private var fanLoaderField:Sprite;
private var file:FileReference = new FileReference();
private var filter:FileFilter = new FileFilter("画像を選択してください", "*.jpg;*.gif;*.png");
public function FlashTest() {
stage.align = StageAlign.TOP_LEFT;
stage.scaleMode = StageScaleMode.NO_SCALE;
canvas = new Sprite();
loaderContent = new Sprite();
menuBar = new MenuBar();
menuBar.addEventListener("load", load);
menuBar.addEventListener("save", save);
menuBar.addEventListener("fullScreen", fullScreen);
menuBar.addEventListener("normal", fullScreen);
addChild(loaderContent);
addChild(canvas);
addChild(menuBar);
fanLoader = new FanLoader(stage.stageWidth/2, stage.stageHeight/2);
fanLoaderField = new Sprite();
fanLoaderField.addChild(fanLoader);
loader = new Loader();
loader.load(new URLRequest(PIG_IMAGE), new LoaderContext(true));
loader.contentLoaderInfo.addEventListener(Event.OPEN, open);
loader.contentLoaderInfo.addEventListener(Event.COMPLETE, complete);
loader.contentLoaderInfo.addEventListener(ProgressEvent.PROGRESS, progress);
file.addEventListener(Event.OPEN, open);
file.addEventListener(Event.COMPLETE, complete);
file.addEventListener(Event.SELECT, select);
file.addEventListener(ProgressEvent.PROGRESS, progress);
stage.addEventListener(Event.RESIZE, resize);
//stage.addEventListener(FullScreenEvent.FULL_SCREEN, fullScreen);
draw();
}
private function init():void{
loaderContent.addChild(loader);
loader.x = -loader.width/2;
loader.y = -loader.height/2;
canvas.x = (stage.stageWidth-loader.width)/2;
canvas.y = (stage.stageHeight-loader.height)/2;
if(!sf) {
sf = new ScrapField(loader.width, loader.height, canvas);
loaderContent.addEventListener(MouseEvent.MOUSE_DOWN, scrapHandler);
}
else {
sf.resize(loader.width, loader.height);
}
menuBar.loadBt.mouseEnabled = true;
menuBar.saveBt.mouseEnabled = true;
}
private function resize(event:Event):void{
draw();
}
private function fullScreen(event:Event):void{
stage.displayState = event.type;
draw();
}
private function draw():void{
fanLoaderField.graphics.clear();
fanLoaderField.graphics.beginFill(0x000000, 0.8);
fanLoaderField.graphics.drawRect(0,0,stage.stageWidth,stage.stageHeight);
fanLoaderField.graphics.endFill();
fanLoader.x = stage.stageWidth/2;
fanLoader.y = stage.stageHeight/2;
loaderContent.x = stage.stageWidth/2;
loaderContent.y = stage.stageHeight/2;
menuBar.draw();
canvas.x = (stage.stageWidth-loader.width)/2;
canvas.y = (stage.stageHeight-loader.height)/2;
}
public function scrapHandler(event:MouseEvent):void{
if(!sf.show) sf.setField();
menuBar.saveBt.mouseEnabled = sf.show;
}
public function open(event:Event):void{
if(sf && sf.show) sf.clearField();
menuBar.loadBt.mouseEnabled = false;
menuBar.saveBt.mouseEnabled = false;
addChild(fanLoaderField);
}
public function complete(event:Event):void{
if(fanLoaderField.parent) removeChild(fanLoaderField);
switch(event.target){
case loader.contentLoaderInfo:
loader.contentLoaderInfo.removeEventListener(Event.OPEN, open);
loader.contentLoaderInfo.removeEventListener(ProgressEvent.PROGRESS, progress);
init();
break;
case file:
loader.loadBytes(file.data);
break;
}
}
public function select(event:Event):void{
file.load();
}
public function progress(event:ProgressEvent):void{
fanLoader.value = event.bytesLoaded/event.bytesTotal*100;
}
public function load(event:Event):void{
file.browse([filter]);
}
public function save(event:Event):void{
stage.displayState = "normal";
menuBar.fullScreenBt.label = "fullScreen";
var _file:FileReference = new FileReference();
var source:BitmapData = new BitmapData(loaderContent.width, loaderContent.height);
var mtrx:Matrix = new Matrix();
mtrx.translate(loaderContent.width/2, loaderContent.height/2);
source.draw(loaderContent,mtrx);
var bmd:BitmapData = new BitmapData(sf.rect.width, sf.rect.height);
bmd.copyPixels(source, sf.rect, new Point());
var jpg:JPGEncoder = new JPGEncoder(100);
var data:ByteArray = jpg.encode(bmd);
_file.save(data, "image.jpg");
_file.addEventListener(Event.OPEN, function ():void{addChild(fanLoaderField);});
_file.addEventListener(Event.COMPLETE, function ():void{removeChild(fanLoaderField);});
_file.addEventListener(ProgressEvent.PROGRESS, progress);
}
}
}
//-----------------------------------------------------
import flash.display.Sprite;
import flash.events.*;
import com.bit101.components.PushButton;
import caurina.transitions.Tweener;
class MenuBar extends Sprite{
public function MenuBar():void{
init();
}
private function init():void{
loadBt = new PushButton(this,10,9,"load",click);
saveBt = new PushButton(this,100,9,"save",click);
fullScreenBt = new PushButton(this,0,9,"fullScreen",click);
loadBt.width = saveBt.width = fullScreenBt.width = 80;
hideBt.y = 30;
hideBtGUI.y = 5;
hideBtField.alpha = 0;
hideBtGUI.graphics.beginFill(0xFFFFFF,0.8);
hideBtGUI.graphics.moveTo(-5,2);
hideBtGUI.graphics.lineTo(5,2);
hideBtGUI.graphics.lineTo(0,-2);
hideBtGUI.graphics.endFill();
addChild(hideBt);
hideBt.addChild(hideBtField);
hideBt.addChild(hideBtGUI);
hideBt.addEventListener(MouseEvent.CLICK, click);
hideBtField.addEventListener(MouseEvent.ROLL_OVER, function ():void{Tweener.addTween(hideBtField,{alpha:1, time:0.5})});
hideBtField.addEventListener(MouseEvent.ROLL_OUT, function ():void{Tweener.addTween(hideBtField,{alpha:0, time:0.5})});
}
public function draw():void{
this.graphics.clear();
this.graphics.beginFill(0x000000, 0.5);
this.graphics.drawRect(0,0,stage.stageWidth,40);
this.graphics.endFill();
fullScreenBt.x = stage.stageWidth-90;
hideBtGUI.x = stage.stageWidth/2;
hideBtField.graphics.clear();
hideBtField.graphics.beginFill(0x000000, 0.5);
hideBtField.graphics.drawRect(0, 0, stage.stageWidth, 10);
hideBtField.graphics.endFill();
}
private function click(event:MouseEvent):void{
if(event.currentTarget == hideBt){
show = !show;
Tweener.addTween(hideBtGUI,{rotation:show ? 0 : 180, time:0.8});
Tweener.addTween(this, {y:show ? 0 : -30, time:0.8})
return;
}
dispatchEvent(new Event(event.target.label));
if(event.currentTarget == fullScreenBt){
fullScreenBt.label = fullScreenBt.label == "fullScreen" ? "normal" : "fullScreen";
}
}
public var show:Boolean = true;
public var loadBt:PushButton;
public var saveBt:PushButton;
public var fullScreenBt:PushButton;
public var hideBt:Sprite = new Sprite();
public var hideBtGUI:Shape = new Shape();
public var hideBtField:Sprite = new Sprite();
}
//------------------------------------------------------------
// ScrapField
//------------------------------------------------------------
import flash.display.DisplayObjectContainer;
import flash.display.Sprite;
import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.display.BitmapDataChannel;
import flash.events.MouseEvent;
import flash.geom.*;
import flash.text.TextField;
import flash.text.TextFormat;
class ScrapField extends Sprite{
private var _parent:DisplayObjectContainer;
//切抜領域のボディ
private var bmp:Bitmap = new Bitmap();
private var _stage:BitmapData;
private var _mask:BitmapData;
private var _gray:BitmapData;
private var body:Sprite = new Sprite();
//切り抜き領域の各頂点
private var upperLeft:ScrapPoint = new ScrapPoint(4,5);
private var upperRight:ScrapPoint = new ScrapPoint(4,5);
private var lowerLeft:ScrapPoint = new ScrapPoint(4,5);
private var lowerRight:ScrapPoint = new ScrapPoint(4,5);
private var upper:ScrapPoint = new ScrapPoint(3,4);
private var lower:ScrapPoint = new ScrapPoint(3,4);
private var left:ScrapPoint = new ScrapPoint(3,4);
private var right:ScrapPoint = new ScrapPoint(3,4);
private var posMessage:MessageField = new MessageField();
private var target:Sprite;
private var _oldX:Number;
private var _oldY:Number;
public var startPoint:Point;
public var finishPoint:Point;
public var show:Boolean = false;
public function ScrapField(width:Number, height:Number, parent:DisplayObjectContainer):void{
if(parent) _parent = parent;
_stage = new BitmapData(width, height, true, 0xaa000000);
_gray = new BitmapData(width, height, true, 0xaa000000);
_mask = new BitmapData(width, height, true, 0x00000000);
bmp.bitmapData = _stage;
this.addChild(bmp);
this.addChild(body);
this.addChild(upper);
this.addChild(lower);
this.addChild(left);
this.addChild(right);
this.addChild(upperLeft);
this.addChild(upperRight);
this.addChild(lowerLeft);
this.addChild(lowerRight);
body.addEventListener(MouseEvent.MOUSE_DOWN, moveCorner);
upperLeft.addEventListener(MouseEvent.MOUSE_DOWN, moveCorner);
upperRight.addEventListener(MouseEvent.MOUSE_DOWN, moveCorner);
lowerLeft.addEventListener(MouseEvent.MOUSE_DOWN, moveCorner);
lowerRight.addEventListener(MouseEvent.MOUSE_DOWN, moveCorner);
upper.addEventListener(MouseEvent.MOUSE_DOWN, moveCorner);
lower.addEventListener(MouseEvent.MOUSE_DOWN, moveCorner);
left.addEventListener(MouseEvent.MOUSE_DOWN, moveCorner);
right.addEventListener(MouseEvent.MOUSE_DOWN, moveCorner);
}
//ScrapFieldを設定する
public function setField():void{
if(!parent) _parent.addChild(this);
show = true;
target = lowerRight;
startPoint = new Point(mouseX, mouseY);
finishPoint = new Point(mouseX, mouseY);
draw();
this.addEventListener(MouseEvent.MOUSE_DOWN, moveCorner);
this.addEventListener(MouseEvent.MOUSE_MOVE, moveCorner);
this.addEventListener(MouseEvent.MOUSE_UP, moveCorner);
}
//ScrapFieldを消す
public function clearField():void{
if(parent) _parent.removeChild(this);
show = false;
target = null;
startPoint = null;
finishPoint = null;
}
//リサイズ
public function resize(width:Number, height:Number):void{
_stage = new BitmapData(width, height, true, 0xaa000000);
_gray = new BitmapData(width, height, true, 0xaa000000);
_mask = new BitmapData(width, height, true, 0x00000000);
bmp.bitmapData.dispose();
bmp.bitmapData = _stage;
draw();
}
//ScrapFieldの再描画
private function draw():void{
if(!show) return;
//各頂点の再描画
upperLeft.point = startPoint;
upperRight.point = new Point(finishPoint.x, startPoint.y);
lowerLeft.point = new Point(startPoint.x, finishPoint.y);
lowerRight.point = finishPoint;
upper.point = Point.interpolate(upperLeft.point, upperRight.point, 0.5);
lower.point = Point.interpolate(lowerLeft.point, lowerRight.point, 0.5);
left.point = Point.interpolate(upperLeft.point, lowerLeft.point, 0.5);
right.point = Point.interpolate(upperRight.point, lowerRight.point, 0.5);
//ボディの再描画
_stage.copyPixels(_gray, _gray.rect, new Point(0, 0));
_stage.copyChannel(_mask, new Rectangle(0,0,Math.abs(finishPoint.x-startPoint.x),Math.abs(finishPoint.y-startPoint.y)),
new Point((startPoint.x<finishPoint.x ? startPoint.x:finishPoint.x), (startPoint.y<finishPoint.y ? startPoint.y:finishPoint.y)),
BitmapDataChannel.ALPHA, BitmapDataChannel.ALPHA);
body.graphics.clear();
body.graphics.lineStyle(4,0x3366ff);
body.graphics.beginFill(0xffffff,0);
body.graphics.drawRect(startPoint.x, startPoint.y, finishPoint.x - startPoint.x, finishPoint.y - startPoint.y);
body.graphics.endFill();
//テキストの表示
posMessage.text(rect.width, rect.height);
//posMessage.text(mouseX, mouseY);
posMessage.x = mouseX+10;
posMessage.y = mouseY+10;
}
//マウスイベント
private function moveCorner(event:MouseEvent):void{
switch(event.type){
case MouseEvent.MOUSE_DOWN:
//境界内をMouseDownしているか?
if(event.currentTarget == this){
if(Math.min(Math.max(mouseX,Math.min(startPoint.x, finishPoint.x)-6),Math.max(startPoint.x, finishPoint.x)+6) == mouseX) {
if(Math.min(Math.max(mouseY,Math.min(startPoint.y, finishPoint.y)-6),Math.max(startPoint.y, finishPoint.y)+6) == mouseY) return;
}
//境界外ならScrapFieldを消す
clearField();
return;
}
target = event.target as Sprite;
_oldX = mouseX;
_oldY = mouseY;
this.addEventListener(MouseEvent.MOUSE_MOVE, moveCorner);
this.addEventListener(MouseEvent.MOUSE_UP, moveCorner);
this.addChild(posMessage);
posMessage.text(rect.width, rect.height);
posMessage.x = mouseX+10;
posMessage.y = mouseY+10;
break;
case MouseEvent.MOUSE_UP:
this.removeEventListener(MouseEvent.MOUSE_MOVE, moveCorner);
this.removeEventListener(MouseEvent.MOUSE_UP, moveCorner);
this.removeChild(posMessage);
break;
//各頂点が移動されたら呼び出される
case MouseEvent.MOUSE_MOVE:
switch(target){
case body: startPoint.x -= _oldX-mouseX; startPoint.y -= _oldY-mouseY;
finishPoint.x -= _oldX-mouseX; finishPoint.y -= _oldY-mouseY; break;
case upperLeft: startPoint.x = mouseX; startPoint.y = mouseY; break;
case upperRight: finishPoint.x = mouseX; startPoint.y = mouseY; break;
case lowerLeft: startPoint.x = mouseX; finishPoint.y = mouseY; break;
case lowerRight: finishPoint.x = mouseX; finishPoint.y = mouseY; break;
case upper: startPoint.y = mouseY; break;
case lower: finishPoint.y = mouseY; break;
case left: startPoint.x = mouseX; break;
case right: finishPoint.x = mouseX; break;
}
_oldX = mouseX;
_oldY = mouseY;
this.addChild(posMessage);
draw();
break;
}
event.updateAfterEvent();
}
public function get rect():Rectangle{
return new Rectangle(Math.min(startPoint.x, finishPoint.x),
Math.min(startPoint.y, finishPoint.y),
Math.abs(startPoint.x-finishPoint.x),
Math.abs(startPoint.y-finishPoint.y));
}
}
class ScrapPoint extends Sprite{
public function ScrapPoint(thick:Number, radius:Number, color:uint=0x3366ff):void{
this.graphics.lineStyle(thick,color);
this.graphics.beginFill(0xffffff);
this.graphics.drawCircle(0, 0, radius);
this.graphics.endFill();
}
public function set point(point:Point):void{
this.x = point.x;
this.y = point.y;
}
public function get point():Point{
return new Point(this.x, this.y);
}
}
class MessageField extends Sprite{
private var txt:TextField;
private var format:TextFormat = new TextFormat("Trebuchet MS", 12, 0xFFFFFF);
public function MessageField():void{
txt = new TextField();
txt.defaultTextFormat = format;
txt.mouseEnabled = false;
txt.x = 5;
txt.y = 1;
addChild(txt);
text(0,0);
draw();
}
private function draw():void{
graphics.clear();
graphics.lineStyle(2,0xFFFFFF,0.8);
graphics.beginFill(0x000000, 0.8);
graphics.drawRoundRect(0,0,txt.textWidth+14,txt.textHeight+6,8);
graphics.endFill();
}
public function text(width:Number, height:Number):void{
txt.text = String(Math.round(width))+"px x "+String(Math.round(height))+"px";
draw();
}
}
//------------------------------------------------------------
// FanLoader
//------------------------------------------------------------
import flash.display.DisplayObjectContainer;
import flash.display.Sprite;
import flash.text.TextField;
import flash.text.TextFormat;
class FanLoader extends Sprite{
private var graphics2:GraphicsPlus;
private var label:TextField;
private var _radius:Number = 0;
private var _value:Number = 0;
public function FanLoader(x:Number = 0, y:Number = 0, radius:Number = 80):void{
graphics2 = new GraphicsPlus();
label = new TextField();
label.mouseEnabled = false;
label.autoSize = "center";
this.addChild(graphics2);
this.addChild(label);
this.x = x;
this.y = y;
this.radius = radius;
}
private function draw():void{
this.graphics2.clear();
this.graphics2.beginFill(color);
this.graphics2.drawFan(0, 0, radius, radius*0.6, -90, value/maximum*360-90);
this.graphics2.endFill();
this.graphics.clear();
label.textColor = textColor;
label.text = String(Math.round(value/maximum*100)+"%");
}
//プロパティ
public var color:uint = 0xAAAAAA;
public var textColor:uint = 0xAAAAAA;
public var maximum:Number = 100;
public var minimum:Number = 0;
public function get radius():Number{
return _radius;
}
public function set radius(val:Number):void{
_radius = val;
label.defaultTextFormat = new TextFormat("Trebuchet MS", val*2/5, textColor, true, null, null, null, null, "center");
draw();
label.x = -val/2;
label.y = -label.textHeight/2;
label.width = val;
}
public function get value():Number{
return _value;
}
public function set value(val:Number):void{
_value = Math.min(100, val);
draw();
}
}
//--------------------------------------------------------
import flash.display.IGraphicsData;
import flash.display.Shader;
import flash.display.Shape;
import flash.geom.Matrix;
import flash.geom.Point;
class GraphicsPlus extends Shape{
public function GraphicsPlus(){
beginFill = this.graphics.beginFill;
beginGradientFill = this.graphics.beginGradientFill;
beginShaderFill = this.graphics.beginShaderFill;
clear = this.graphics.clear;
curveTo = this.graphics.curveTo;
drawCircle = this.graphics.drawCircle;
drawEllipse = this.graphics.drawEllipse;
drawGraphicsData = this.graphics.drawGraphicsData;
drawPath = this.graphics.drawPath;
drawRect = this.graphics.drawRect;
drawRoundRect = this.graphics.drawRoundRect;
drawRoundRectComplex = this.graphics.drawRoundRectComplex;
drawTriangles = this.graphics.drawTriangles;
endFill = this.graphics.endFill;
lineGradientStyle = this.graphics.lineGradientStyle;
lineShaderStyle = this.graphics.lineShaderStyle;
lineStyle = this.graphics.lineStyle;
lineTo = this.graphics.lineTo;
moveTo = this.graphics.moveTo;
}
// 扇形を描くメソッド
// x:中心のx座標 y:中心のy座標
// r1:外円の半径 r2:内円の半径
// a1:始点の角度 a2:終点の角度
public function drawFan(x:Number, y:Number, r1:Number, r2:Number, a1:Number, a2:Number):void{
//角度をラジアンに直す
var radian1:Number = a1*Math.PI/180;
var radian2:Number = a2*Math.PI/180;
// 外円の描画
draw(x, y, r1, radian1, radian2, false);
// 内円の描画
draw(x, y, r2, radian2, radian1, true);
}
//扇形の外円・内円の描画
//参考サイト丸写し…
private function draw(x:Number, y:Number, r:Number, t1:Number, t2:Number, lineTo:Boolean):void{
var div:Number = Math.max(1, Math.floor(Math.abs(t1 - t2) / 0.4));
var lx:Number;
var ly:Number;
var lt:Number;
for (var i:int = 0; i <= div; i++) {
var ct:Number = t1 + (t2 - t1)*i/div;
var cx:Number = Math.cos(ct)*r + x;
var cy:Number = Math.sin(ct)*r + y;
if(i==0){
if(lineTo) this.graphics.lineTo(cx, cy);
else this.graphics.moveTo(cx, cy);
}else{
var cp:Point = getControlPoint(new Point(lx, ly), lt+Math.PI/2, new Point(cx, cy), ct+Math.PI/2);
this.graphics.curveTo(cp.x, cp.y, cx, cy);
}
lx = cx;
ly = cy;
lt = ct;
}
}
//コントロールポイントの計算
//参考サイト丸写し…
private function getControlPoint(p1:Point, t1:Number, p2:Point, t2:Number):Point{
var dif:Point = p2.subtract(p1);
var l12:Number = Math.sqrt(dif.x*dif.x + dif.y*dif.y);
var t12:Number = Math.atan2(dif.y, dif.x);
var l13:Number = l12*Math.sin(t2 - t12)/Math.sin(t2 - t1);
return new Point(p1.x+l13*Math.cos(t1), p1.y+l13*Math.sin(t1));
}
//------------------------------------------------
//「Graphicsクラスのサブクラス」風に見せるための変数
public var beginFill:Function;
public var beginGradientFill:Function;
public var beginShaderFill:Function;
public var clear:Function;
public var curveTo:Function;
public var drawCircle:Function;
public var drawEllipse:Function;
public var drawGraphicsData:Function;
public var drawPath:Function;
public var drawRect:Function;
public var drawRoundRect:Function;
public var drawRoundRectComplex:Function;
public var drawTriangles:Function;
public var endFill:Function;
public var lineGradientStyle:Function;
public var lineShaderStyle:Function;
public var lineStyle:Function;
public var lineTo:Function;
public var moveTo:Function;
}