矩形選択ツール
矩形選択ツールをもうちょっと使いやすく。
*
* 矩形を描いた後にドラッグやカーソルキーで
* 変形できる。
*
* 矩形選択ツールの部分以外は最低限の機能。
*
* 参考
* http://iccii.seesaa.net/article/28058268.html
*
/**
* Copyright umhr ( http://wonderfl.net/user/umhr )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/qHW9
*/
/*
* 矩形選択ツールをもうちょっと使いやすく。
*
* 矩形を描いた後にドラッグやカーソルキーで
* 変形できる。
*
* 矩形選択ツールの部分以外は最低限の機能。
*
* 参考
* http://iccii.seesaa.net/article/28058268.html
* */
package
{
import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.display.Sprite;
import flash.display.Sprite;
import flash.events.Event;
import flash.events.MouseEvent;
import flash.geom.Matrix;
import flash.text.TextField;
import flash.text.TextFormat;
import com.bit101.components.PushButton;
/**
* ...
* @author umhr
*/
[SWF(backgroundColor="0x777777")]
public class Main extends Sprite
{
private var _highlite:Highlite;
private var _canvas:Sprite;
private var _bitmap:Bitmap;
public function Main():void
{
stage.scaleMode = "noScale";
stage.align = "TL";
_canvas = new Sprite();
this.addChild(_canvas);
new PushButton(this,0,0,"LOAD IMG",atLoad);
new PushButton(this,stage.stageWidth-100,0,"SAVE PNG",atSave);
}
private function atLoad(event:MouseEvent):void{
var loadFile:LoadFile = new LoadFile();
loadFile.atComplete = atComplete;
loadFile.Start();
}
private function atComplete(event:Event):void {
while (_canvas.numChildren > 0) {
_canvas.removeChildAt(0);
}
//読み込んだ画像を中央に置く
_bitmap = event.target.content;
_bitmap.x = Math.floor((stage.stageWidth - _bitmap.width) / 2);
_bitmap.y = Math.floor((stage.stageHeight - _bitmap.height) / 2);
_canvas.addChild(_bitmap);
//矩形選択ツール
_highlite = new Highlite(_bitmap.x, _bitmap.y, _bitmap.width, _bitmap.height);
_canvas.addChild(_highlite);
}
//画像の書き出しとりあえずPNG固定
private function atSave(event:MouseEvent):void {
if (_canvas.numChildren == 0 || _highlite.selectedRectangle.width*_highlite.selectedRectangle.height == 0) { return };
var bitmapData:BitmapData = new BitmapData(_highlite.selectedRectangle.width,_highlite.selectedRectangle.height,true,0);
bitmapData.draw(_bitmap, new Matrix(1, 0, 0, 1, -_highlite.selectedRectangle.x, -_highlite.selectedRectangle.y));
SaveImage.PNGfromDisplayObject(new Bitmap(bitmapData));
}
}
}
import flash.display.Sprite;
import flash.events.Event;
import flash.events.KeyboardEvent;
import flash.events.MouseEvent;
import flash.geom.Point;
import flash.geom.Rectangle;
import flash.utils.Dictionary;
class Highlite extends Sprite {
private var _in:Point;
private var _rectangle:Rectangle;
public var selectedRectangle:Rectangle;
private var _selectedArea:SelectedArea;
public var onChange:Function = function(selectedRectangle:Rectangle):void{};
public function Highlite(x:Number=0,y:Number=0,width:Number=0,height:Number=0){
_in = new Point();
rectangle = new Rectangle(x, y, width, height);
selectedRectangle = new Rectangle();
_selectedArea = new SelectedArea();
this.addChild(_selectedArea);
this.addEventListener(Event.ADDED_TO_STAGE, onAddedToStage);
this.addEventListener(Event.REMOVED_FROM_STAGE, onRemoveFromStage);
}
private function onAddedToStage(event:Event):void {
this.removeEventListener(Event.ADDED_TO_STAGE, onAddedToStage);
stage.addEventListener(MouseEvent.MOUSE_DOWN, onDown);
stage.addEventListener(MouseEvent.MOUSE_MOVE, onMove);
stage.addEventListener(MouseEvent.MOUSE_UP, onUp);
stage.addEventListener(KeyboardEvent.KEY_DOWN, onKeyDown);
}
private function onRemoveFromStage(event:Event):void {
this.removeEventListener(Event.ADDED_TO_STAGE, onAddedToStage);
this.removeEventListener(Event.REMOVED_FROM_STAGE, onRemoveFromStage);
stage.removeEventListener(MouseEvent.MOUSE_DOWN, onDown);
stage.removeEventListener(MouseEvent.MOUSE_MOVE, onMove);
stage.removeEventListener(MouseEvent.MOUSE_UP, onUp);
stage.removeEventListener(KeyboardEvent.KEY_DOWN, onKeyDown);
}
//矢印キーで選択域を移動できる。
private function onKeyDown(event:KeyboardEvent):void {
if (_selectedArea.selected < 0) { return };
var keyObj:Object = { 37:[ -1, 0], 38:[0, -1], 39:[1, 0], 40:[0, 1] };
if (keyObj[event.keyCode]) {
//if (!isNaN(_selectedArea.dictionary[stage.focus]) && _selectedArea.dictionary[stage.focus] < 9) {
//var selected:int = _selectedArea.dictionary[stage.focus];
if (_selectedArea.selected < 9) {
var selected:int = _selectedArea.selected;
var pointTL:Point = selectedRectangle.topLeft;
var pointBR:Point = selectedRectangle.bottomRight;
if (selected == 4) {
pointTL.x += keyObj[event.keyCode][0];
pointBR.x += keyObj[event.keyCode][0];
}else if(selected%3 == 0){
pointTL.x += keyObj[event.keyCode][0];
}else if(selected%3 == 2){
pointBR.x += keyObj[event.keyCode][0];
}
if (selected == 4) {
pointTL.y += keyObj[event.keyCode][1];
pointBR.y += keyObj[event.keyCode][1];
}else if(selected <= 2){
pointTL.y += keyObj[event.keyCode][1];
}else if(selected >= 6){
pointBR.y += keyObj[event.keyCode][1];
}
target(pointTL, pointBR);
}
}
//trace(event.keyCode, stage.focus, _selectedArea.dictionary[stage.focus],keyObj[event.keyCode])
}
private function target(a:Point, b:Point):void {
var x:Number = Math.max(0, Math.min(a.x, b.x));
var y:Number = Math.max(0, Math.min(a.y, b.y));
var w:Number = Math.min(rectangle.width, Math.max(a.x, b.x)) - x;
var h:Number = Math.min(rectangle.height, Math.max(a.y, b.y)) - y;
if (w < 0 || h < 0) { return };
this.graphics.clear();
this.graphics.beginFill(0xCC3333,0.5);
this.graphics.drawRect(0, 0, rectangle.width, rectangle.height);
this.graphics.drawRect(x, y, w, h);
_selectedArea.setSize(x, y, w, h);
this.graphics.endFill();
selectedRectangle = new Rectangle(x, y, w, h);
onChange(selectedRectangle);
}
public function set rectangle(rect:Rectangle):void{
this.x = rect.x;
this.y = rect.y;
_rectangle = rect;
}
public function get rectangle():Rectangle{
return _rectangle;
}
private var _isUp:Boolean;
private function onUp(event:MouseEvent):void {
_isUp = true;
}
private function onDown(event:MouseEvent):void {
if (_selectedArea.dictionary[event.target] == undefined || !_isUp) {
_isUp = false;
_in = new Point(this.mouseX, this.mouseY);
_selectedArea.selected = -1;
}else if (!isNaN(_selectedArea.dictionary[event.target])) {
_selectedArea.handlePoint = new Point(this.mouseX, this.mouseY);
_selectedArea.selected = _selectedArea.dictionary[event.target];
}
}
//マウスドラッグ時
private function onMove(event:MouseEvent):void {
_selectedArea.isMouseOver = selectedRectangle.contains(this.mouseX, this.mouseY);
if (!event.buttonDown) { return };
if (_selectedArea.dictionary[event.target] == undefined && !_isUp) {
//選択域を作る
target(_in, new Point(this.mouseX, this.mouseY));
}else if (_selectedArea.selected > -1) {
//選択域をドラッグする
var selected:int = _selectedArea.selected;
if (selected == 100) { return };
var subtract:Point = _selectedArea.handlePoint.subtract(new Point(this.mouseX, this.mouseY));
var pointTL:Point = selectedRectangle.topLeft;
var pointBR:Point = selectedRectangle.bottomRight;
if (selected == 4) {
pointTL.x -= subtract.x;
pointBR.x -= subtract.x;
}else if(selected%3 == 0){
pointTL.x -= subtract.x;
}else if(selected%3 == 2){
pointBR.x -= subtract.x;
}
if (selected == 4) {
pointTL.y -= subtract.y;
pointBR.y -= subtract.y;
}else if(selected <= 2){
pointTL.y -= subtract.y;
}else if(selected >= 6){
pointBR.y -= subtract.y;
}
target(pointTL, pointBR);
_selectedArea.handlePoint = new Point(this.mouseX, this.mouseY);
}
}
}
class SelectedArea extends Sprite {
public var handlePoint:Point;
public var selected:int;
private var _handles:Array;
public var dictionary:Dictionary;
private var _handleWidth:int;
private var _handleHeight:int;
private var _isMouseOver:Boolean;
public function SelectedArea() {
super();
dictionary = new Dictionary();
dictionary[this] = 100;
handlePoint = new Point();
selected = -1;
_handles = [];
for (var i:int = 0; i < 9; i++) {
_handles[i] = new Sprite();
this.addChild(_handles[i]);
dictionary[_handles[i]] = i;
}
}
//ハンドルを設置
private function setHandleGraphics(width:int, height:int):void {
if ((_handleWidth == width && _handleHeight == height) && _isMouseOver) {
return;
}
for (var i:int = 0; i < 9; i++) {
_handles[i].graphics.clear();
_handles[i].graphics.beginFill(0xCCCCCC, 0);
_handles[i].graphics.drawRect(0,0,width,height);
_handles[i].graphics.endFill();
_handles[i].graphics.lineStyle(1, 0x666666);
if(i == 0){
_handles[i].graphics.moveTo(0, height);
_handles[i].graphics.lineTo(width, height);
_handles[i].graphics.lineTo(width, 0);
}else if(i == 1){
_handles[i].graphics.moveTo(0, 0);
_handles[i].graphics.lineTo(0, height);
_handles[i].graphics.lineTo(width, height);
_handles[i].graphics.lineTo(width, 0);
}else if(i == 2){
_handles[i].graphics.moveTo(0, 0);
_handles[i].graphics.lineTo(0, height);
_handles[i].graphics.lineTo(width, height);
}else if(i == 3){
_handles[i].graphics.moveTo(0,0);
_handles[i].graphics.lineTo(width, 0);
_handles[i].graphics.lineTo(width, height);
_handles[i].graphics.lineTo(0,height);
}else if(i == 4){
_handles[i].graphics.moveTo(0,0);
_handles[i].graphics.lineTo(0, height);
_handles[i].graphics.lineTo(width, height);
_handles[i].graphics.lineTo(width, 0);
_handles[i].graphics.lineTo(0, 0);
}else if(i == 5){
_handles[i].graphics.moveTo(width, height);
_handles[i].graphics.lineTo(0,height);
_handles[i].graphics.lineTo(0, 0);
_handles[i].graphics.lineTo(width,0);
}else if(i == 6){
_handles[i].graphics.moveTo(0, 0);
_handles[i].graphics.lineTo(width,0);
_handles[i].graphics.lineTo(width, height);
}else if(i == 7){
_handles[i].graphics.moveTo(0, height);
_handles[i].graphics.lineTo(0, 0);
_handles[i].graphics.lineTo(width,0);
_handles[i].graphics.lineTo(width, height);
}else if(i == 8){
_handles[i].graphics.moveTo(0, height);
_handles[i].graphics.lineTo(0, 0);
_handles[i].graphics.lineTo(width,0);
}
}
_handleWidth = width;
_handleHeight = height;
}
//マウスオーバー時ハンドル表示
public function set isMouseOver(isOver:Boolean):void {
if (_isMouseOver == isOver) {
if (isOver || _handleWidth*_handleHeight == 0) {
return;
}
};
if (isOver) {
setHandleGraphics(_handleWidth, _handleHeight);
}else {
for (var i:int = 0; i < 9; i++) {
_handles[i].graphics.clear();
}
}
_isMouseOver = isOver;
}
//ハンドルの位置を調整
public function setSize(x:int, y:int, width:int, height:int):void {
this.x = x;
this.y = y;
//透明のエリアがあることによって、選択域の中のハンドルがない部分があることを検地させる
this.graphics.clear();
this.graphics.beginFill(0x000000,0);
this.graphics.drawRect(0, 0, width, height);
this.graphics.endFill();
var w:int = Math.floor(Math.min(width / 4, 20));
var h:int = Math.floor(Math.min(height / 4, 20));
setHandleGraphics(w, h);
_handles[1].x = (width - _handles[1].width) / 2;
_handles[2].x = width - _handles[2].width+1;
_handles[3].y = (height - _handles[3].height) / 2;
_handles[4].x = (width - _handles[4].width) / 2;
_handles[4].y = (height - _handles[4].height) / 2;
_handles[5].x = width - _handles[5].width+1;
_handles[5].y = (height - _handles[5].height) / 2;
_handles[6].y = (height - _handles[6].height)+1;
_handles[7].x = (width - _handles[7].width) / 2;
_handles[7].y = (height - _handles[7].height) +1;
_handles[8].x = width - _handles[8].width+1;
_handles[8].y = (height - _handles[8].height)+1;
}
}
import flash.display.Loader;
import flash.events.Event;
import flash.net.FileReference;
import flash.system.LoaderContext;
class LoadFile{
private var _fileReference:FileReference;
public var atComplete:Function = function(event:Event):void{};
/**
* 開始
*
*/
public function Start():void
{
if(_fileReference){
return;
}
_fileReference = new FileReference();
_fileReference.browse();
_fileReference.addEventListener(Event.SELECT,atSelect);
}
/**
* ファイルの選択が完了すると動く
* @param event
*
*/
private function atSelect(event:Event):void{
_fileReference.removeEventListener(Event.SELECT,atSelect);
_fileReference.addEventListener(Event.COMPLETE,atFileComplete);
_fileReference.load();
}
/**
* 選択したファイルを読み込み完了すると動く
* @param event
*
*/
private function atFileComplete(event:Event):void{
_fileReference.removeEventListener(Event.COMPLETE,atFileComplete);
var loader:Loader = new Loader();
loader.loadBytes(event.target.data,new LoaderContext());
loader.contentLoaderInfo.addEventListener(Event.COMPLETE,atBytesComplete);
}
/**
* 読み込んだファイルのバイトアレイを変換完了で動く
* @param event
*
*/
private function atBytesComplete(event:Event):void{
event.target.removeEventListener(Event.COMPLETE,atBytesComplete);
atComplete(event);
}
}
import com.adobe.images.JPGEncoder;
import com.adobe.images.PNGEncoder;
import flash.display.BitmapData;
import flash.display.DisplayObject;
import flash.geom.Matrix;
import flash.net.FileReference;
import flash.utils.ByteArray;
class SaveImage{
public function SaveImage(){};
/**
* PNG画像を書き出すためのメソッド
* @param displayObject
* @param is32BitColor//アルファチャンネル付きか否か
* @param isClearEdge//1pxの余白を付けるか否か
* @param isEven//画像の大きさ(縦横)を偶数にするか否か
*
*/
public static function PNGfromDisplayObject(displayObject:DisplayObject,is32BitColor:Boolean = true,isClearEdge:Boolean=false,isEven:Boolean=false):void{
var width:int = displayObject.width+(isClearEdge?2:0);
var height:int = displayObject.height+(isClearEdge?2:0);
var txty:int = isClearEdge?1:0;
if(isEven){
width += width%2;
height += height%2;
}
var bitmapData:BitmapData = new BitmapData(width,height,is32BitColor,0xFFFFFF);
bitmapData.draw(displayObject,new Matrix(1,0,0,1,txty,txty));
var byteArray:ByteArray = PNGEncoder.encode(bitmapData);
var fileReference:FileReference = new FileReference();
fileReference.save(byteArray,"image.png");
}
/**
* JPG画像を書き出すためのメソッド
* @param displayObject
* @param quality//画質0-100
*
*/
public static function JPGfromDisplayObject(displayObject:DisplayObject,quality:Number=50):void{
var width:int = displayObject.width;
var height:int = displayObject.height;
var bitmapData:BitmapData = new BitmapData(width,height);
bitmapData.draw(displayObject);
var jPGEncoder:JPGEncoder = new JPGEncoder(quality);
var byteArray:ByteArray = jPGEncoder.encode(bitmapData);
var fileReference:FileReference = new FileReference();
fileReference.save(byteArray,"image.jpg");
}
}