TOYCAMERA風画像処理
/**
* Copyright okoi ( http://wonderfl.net/user/okoi )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/xTG1
*/
package
{
import flash.display.Sprite;
import flash.events.Event;
import flash.events.MouseEvent;
import flash.display.BitmapData;
import flash.display.Bitmap;
import flash.filters.BlurFilter;
import flash.filters.ColorMatrixFilter;
import flash.geom.Point;
import flash.geom.Matrix;
import flash.system.Security;
[SWF(width = "465", height = "465")]
/**
* ...
* @author
*/
public class Main extends Sprite
{
public static const WIDTH:int = 465;
public static const HEIGHT:int = 465;
private var canvas:BitmapData = null;
private var canvasBmp:Bitmap;
private var image:Image;
private var config:Config;
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
Security.allowDomain("assets.wonderfl.net");
Security.loadPolicyFile("http://assets.wonderfl.net/crossdomain.xml");
graphics.beginFill(0);
graphics.drawRect(0, 0, WIDTH, HEIGHT);
graphics.endFill();
canvasBmp = new Bitmap();
addChild( canvasBmp );
config = new Config();
addChild( config );
image = new Image("http://assets.wonderfl.net/images/related_images/9/97/97f0/97f0114ea5c136ce08bc39b659617305b532dba2", WIDTH-20, HEIGHT-20, LoadedImage );
addEventListener( Event.ENTER_FRAME, EnterFrameHandler );
}
private function LoadedImage( img:Image ) : void
{
canvas = img.image.clone();
canvasBmp.bitmapData = canvas;
canvasBmp.x = WIDTH / 2 - canvas.width / 2;
canvasBmp.y = HEIGHT / 2 - canvas.height / 2;
config.SetGradientCenter( canvas.width / 2, canvas.height / 2 );
ReRender();
stage.addEventListener( MouseEvent.CLICK, ClickImage );
}
/**
* ブラーをかける
* @param centerX
* @param centerY
* @param r
* @param src
* @param dst
* @param type
*/
private function Blur(centerX:Number, centerY:Number, r:Number, src:BitmapData, dst:BitmapData, type:String) : void
{
var sp:Sprite = new Sprite();
// ブラー部分を作成
var blurBmpd:BitmapData = src.clone();
var blurBmp:Bitmap = new Bitmap(blurBmpd);
blurBmpd.applyFilter( blurBmpd, blurBmpd.rect, new Point(), new BlurFilter(4, 4, 3));
sp.addChild(blurBmp);
// マスク素材作成
var maskBmpd:BitmapData = src.clone();
var maskBmp:Bitmap = new Bitmap(maskBmpd);
maskBmp.cacheAsBitmap = true;
sp.addChild(maskBmp);
var mask:Sprite = CreateGradientSprite(centerX,centerY, src.width, src.height, type);
sp.addChild( mask );
mask.cacheAsBitmap = true;
maskBmp.mask = mask;
dst.draw( sp );
while ( sp.numChildren ) sp.removeChildAt(0);
blurBmpd.dispose();
blurBmpd = null;
maskBmpd.dispose();
maskBmpd = null;
maskBmp = null;
mask = null;
sp = null;
}
/**
* グラデーションマスク作成
* @param centerX
* @param centerY
* @param type "linear" or "radial"
* @return
*/
private function CreateGradientSprite( centerX:Number, centerY:Number, width:Number, height:Number, type:String ) : Sprite
{
var sprite:Sprite = new Sprite();
var colors:Array;
var alphas:Array;
var ratios:Array;
var mat:Matrix = new Matrix();
if ( type == "linear" )
{
colors = [0x000000, 0x000000, 0x000000];
alphas = [0, 1, 0];
ratios = [0, 128, 255];
mat.createGradientBox( width, height, Math.PI / 2, 0, centerY - height/2 );
}else
if ( type == "radial" )
{
colors = [0x000000, 0x000000];
alphas = [1, 0];
ratios = [0, 255];
mat.createGradientBox( width, height, 0, centerX - width/2, centerY - height/2 );
}
sprite.graphics.beginGradientFill( type, colors, alphas, ratios, mat );
sprite.graphics.drawRect(0, 0, width, height);
sprite.graphics.endFill();
return sprite;
}
/**
* コントラスト調整
* @param value
* @param src
* @param dst
*/
private function Contrast( value:Number, src:BitmapData, dst:BitmapData ) : void
{
var matrix:Array = [
1 + value, 0, 0, 0, -(128*value),
0, 1 + value, 0, 0, -(128*value),
0, 0, 1 + value, 0, -(128*value),
0, 0, 0, 1, 0
];
dst.applyFilter(src, src.rect, new Point, new ColorMatrixFilter(matrix));
}
/**
* 再レンダリング
*/
private function ReRender() : void
{
if ( canvas == null ) return;
canvas.draw( image.image );
Contrast( config.contrast, canvas, canvas );
Blur( config.gradientCenterX, config.gradientCenterY, 100, canvas, canvas, config.gradientType );
}
/**
* 毎フレーム処理
* @param e
*/
private function EnterFrameHandler( e:Event ) : void
{
if ( config.changed )
{
ReRender();
config.changed = false;
}
}
private function ClickImage( e:MouseEvent ) : void
{
var point:Point = new Point( e.localX, e.localY );
point = canvasBmp.globalToLocal( point );
config.SetGradientCenter( point.x, point.y );
}
}
}
import flash.display.BitmapData;
import flash.display.Loader;
import flash.display.LoaderInfo;
import flash.net.URLRequest;
import flash.geom.Matrix;
import flash.display.Sprite;
import com.bit101.components.*;
import flash.events.Event;
import flash.events.MouseEvent;
/**
* ...
* @author
*/
class Image
{
private var loader:Loader = null;
private var loaderInfo:LoaderInfo = null;
protected var baseImage:BitmapData;
protected var _width:int;
protected var _height:int;
protected var _image:BitmapData;
private var loadCompleteCallback:Function = null;
public function Image( path:String, w:int, h:int, callback:Function )
{
_width = w;
_height = h;
loadCompleteCallback = callback;
loader = new Loader();
loaderInfo = loader.contentLoaderInfo;
loaderInfo.addEventListener( Event.COMPLETE, LoadCompleteHandler );
loader.load( new URLRequest( path ) );
}
private function LoadCompleteHandler( e:Event ) : void
{
loaderInfo.removeEventListener( Event.COMPLETE, LoadCompleteHandler );
baseImage = new BitmapData( loader.width, loader.height, true, 0 );
baseImage.draw( loader );
var scaleX:Number = Math.min( _width / loader.width, 1 );
var scaleY:Number = Math.min( _height / loader.height, 1 );
var scale:Number = ( scaleX < scaleY ) ? scaleX : scaleY;
_width = loader.width * scale;
_height = loader.height * scale;
_image = new BitmapData( _width, _height, true, 0 );
_image.draw( loader, new Matrix(scale, 0, 0, scale, 0, 0) );
loader = null;
loaderInfo = null;
if ( loadCompleteCallback != null ) loadCompleteCallback( this );
}
public function get image():BitmapData { return _image; }
}
/**
* ...
* @author
*/
class Config extends Window
{
public var gradientType:String;
public var contrast:Number;
public var changed:Boolean;
public var gradientCenterX:Number;
public var gradientCenterY:Number;
private var _gradientCenterLabel:Label;
public function Config()
{
this.title = "Config";
this.shadow = true;
this.width = 200;
this.height -= 5;
CreateLabel( 5, 5, "GradientType" );
CreateRadioButton( 10, 25, "linear", true );
CreateRadioButton( 60, 25, "radial", false );
CraeteSlider( 5, 35, -1, 1, "Contrast" );
_gradientCenterLabel = CreateLabel( 5, 50, "" );
gradientType = "linear";
contrast = 0;
changed = false;
this.addEventListener( MouseEvent.CLICK, ClickHandler );
}
private function CreateLabel( x:Number, y:Number, text:String ) : Label
{
var label:Label = new Label(this.content, x, y, text);
return label;
}
private function CreateRadioButton( x:Number, y:Number, text:String, check:Boolean ) : RadioButton
{
var button:RadioButton = new RadioButton( this.content, x, y, text, check, onChange );
return button;
}
private function CraeteSlider( x:Number, y:Number, min:Number, max:Number, text:String ) : HUISlider
{
var slider:HUISlider = new HUISlider( this.content, x, y, text, onChange );
slider.maximum = 1;
slider.minimum = -1;
slider.tick = 0.1
return slider;
}
public function SetGradientCenter( x:Number, y:Number ) : void
{
gradientCenterX = x;
gradientCenterY = y;
changed = true;
_gradientCenterLabel.text = "GradientCenter x=" + x + "px, y=" + y + "px";
}
private function onChange( e:Event ) : void
{
if ( e.currentTarget is RadioButton )
{
gradientType = (e.currentTarget as RadioButton).label;
}else
if ( e.currentTarget is HUISlider )
{
contrast = (e.currentTarget as HUISlider).value;
}
changed = true;
}
private function ClickHandler( e:MouseEvent ) : void
{
e.stopImmediatePropagation();
e.stopPropagation();
}
}