CMYK Separater
テキトウな感じでCMYK色分解
/**
* Copyright zahir ( http://wonderfl.net/user/zahir )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/kI5G
*/
package
{
import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.display.Sprite;
import flash.events.Event;
import flash.geom.Matrix;
[SWF(widht="465", height="465", frameRate="30", backgroundColor="0xFFFFFF")]
public class CMYKSeparater extends Sprite
{
private var container:Sprite;
private var loadBtn:ImageLoadButton;
private var layers:Array;
public function CMYKSeparater()
{
addChild( container = new Sprite() );
addChild( loadBtn = new ImageLoadButton() );
loadBtn.addEventListener( LoadImageEvent.COMPLETE, onLoaded );
addEventListener( Event.ENTER_FRAME, onEnter );
}
private function onEnter( event:Event ):void
{
if(layers){
move();
}
}
private function move():void
{
var m:int = 15;
var w:int = stage.stageWidth;
var h:int = stage.stageHeight;
for(var i:int = 0, len:int = layers.length; i<len; i++){
var l:Layer = layers[i] as Layer;
l.x = (w - l.width) >> 1;
l.y = (h - l.height) >> 1;
l.x += Math.random() * m;
l.y += Math.random() * m;
}
}
private function onLoaded( event:LoadImageEvent ):void
{
var src:BitmapData = event.bitmapData;
var w:int;
var h:int;
var scale:Number = 1;
var mtx:Matrix = new Matrix();
if( src.width > src.height ){
scale = 300 / src.width;
}else{
scale = 300 / src.height;
}
w = src.width * scale;
h = src.height * scale;
mtx.scale( scale, scale );
var bd:BitmapData = new BitmapData( w,h );
bd.draw( src, mtx );
separate( bd );
}
private function separate( bd:BitmapData ):void
{
var w:int = bd.width;
var h:int = bd.height;
var c:BitmapData = new BitmapData( w,h, true, 0xFF000000);
var m:BitmapData = new BitmapData( w,h, true, 0xFF000000);
var y:BitmapData = new BitmapData( w,h, true, 0xFF000000);
var k:BitmapData = new BitmapData( w,h, true, 0xFF000000);
new Job( bd, c, ChannelCMYK.C );
new Job( bd, m, ChannelCMYK.M );
new Job( bd, y, ChannelCMYK.Y );
new Job( bd, k, ChannelCMYK.K );
if( layers ){
(layers[0] as Layer).setBitmapData( c );
(layers[1] as Layer).setBitmapData( m );
(layers[2] as Layer).setBitmapData( y );
(layers[3] as Layer).setBitmapData( k );
}else{
layers = [
new Layer( c ),
new Layer( m ),
new Layer( y ),
new Layer( k )
];
for(var i:int = 0 , len:int = layers.length ; i<len; i++){
var l:Layer = layers[ (len-1) - i] as Layer;
container.addChild( l );
}
}
}
}
}
import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.display.BlendMode;
import flash.display.Graphics;
import flash.display.Loader;
import flash.display.Shader;
import flash.display.ShaderJob;
import flash.display.Sprite;
import flash.events.Event;
import flash.events.MouseEvent;
import flash.filters.GlowFilter;
import flash.net.FileFilter;
import flash.net.FileReference;
import flash.text.TextField;
import flash.utils.ByteArray;
import mx.utils.Base64Decoder;
class Layer extends Sprite
{
private var g:Graphics;
public function Layer( bitmapData:BitmapData )
{
g = graphics;
setBitmapData( bitmapData );
this.blendMode = BlendMode.MULTIPLY
}
public function setBitmapData( bitmapData:BitmapData ):void
{
draw( bitmapData );
}
private function draw( bd:BitmapData ):void
{
g.clear();
g.beginBitmapFill( bd );
g.drawRect( 0,0, bd.width, bd.height );
g.endFill();
}
}
class Job
{
public function Job( src:BitmapData, dst:BitmapData, channel:int = 0, alpha:Boolean = true )
{
var s:ChannelCMYK = new ChannelCMYK( src, channel, alpha );
var sj:ShaderJob = new ShaderJob( s, dst, dst.width, dst.height );
sj.start( true );
}
}
class LoadImageEvent extends Event
{
public static const COMPLETE:String = "image_load_complete";
public var bitmapData:BitmapData;
public function LoadImageEvent( type:String, bitmapData:BitmapData, bubbles:Boolean = false, cancelable:Boolean = false )
{
super( type, bubbles, cancelable );
this.bitmapData = bitmapData;
}
}
class ButtonBase extends Sprite
{
private var t:TextField;
private var w:int;
private var h:int;
private var g:Graphics;
private var overFlg:Boolean = false;
public function ButtonBase( txt:String )
{
addChild( t = new TextField() );
t.autoSize = "left";
t.mouseEnabled = false;
buttonMode = true;
text = txt;
g = graphics;
draw( 0xFFFFFF, 0x666666 );
addEventListener( MouseEvent.MOUSE_OVER, onOver );
addEventListener( MouseEvent.MOUSE_DOWN, onDown );
}
private function onOver( mouseEvent:MouseEvent ):void
{
stage.addEventListener( MouseEvent.MOUSE_OUT, onOut );
overFlg = true;
draw( 0xCCCCCC, 0x666666 );
}
private function onOut( mouseEvent:MouseEvent ):void
{
stage.removeEventListener( MouseEvent.MOUSE_OUT, onOut );
overFlg = false;
draw( 0xFFFFFF, 0x666666 );
}
private function onDown( mouseEvent:MouseEvent ):void
{
stage.addEventListener( MouseEvent.MOUSE_UP, onUp );
draw( 0xFFFFFF, 0x0099FF );
}
private function onUp( mouseEvent:MouseEvent ):void
{
stage.removeEventListener( MouseEvent.MOUSE_UP, onUp );
if( overFlg )
{
draw( 0xCCCCCC, 0x666666 );
}else{
draw( 0xFFFFFF, 0x666666 );
}
}
public function get text():String
{
return t.text;
}
public function set text( txt:String ):void
{
t.text = txt;
w = t.width + 16;
h = t.height + 5;
t.x = 8;
t.y = 2.5;
}
public function draw( color:uint, stroke:uint):void
{
g.clear();
g.lineStyle( 1, stroke);
g.beginFill( color );
g.drawRect( 0,0, w,h );
g.endFill();
}
}
class ImageLoadButton extends ButtonBase
{
private const FILTER:Array = [ new FileFilter("load image", "*.jpg;*.png") ];
private var fr:FileReference;
private var l:Loader;
public function ImageLoadButton()
{
super("load image");
fr = new FileReference();
l = new Loader();
addEventListener(MouseEvent.CLICK, onClick);
}
private function onClick( event:MouseEvent ):void
{
fr.addEventListener(Event.SELECT, onSelect);
fr.browse( FILTER );
}
private function onSelect( event:Event ):void
{
fr.removeEventListener(Event.SELECT, onSelect);
fr.addEventListener(Event.COMPLETE, onLoaded );
fr.load();
}
private function onLoaded( event:Event ):void
{
fr.removeEventListener(Event.COMPLETE, onLoaded );
l.contentLoaderInfo.addEventListener(Event.COMPLETE, onDecode);
l.loadBytes( fr.data );
}
private function onDecode( event:Event ):void
{
l.contentLoaderInfo.removeEventListener(Event.COMPLETE, onDecode );
this.dispatchEvent( new LoadImageEvent( LoadImageEvent.COMPLETE, (l.content as Bitmap).bitmapData ) );
}
}
class ChannelCMYK extends Shader{
static private var code:ByteArray;
// static initializer
{
private static var dec:Base64Decoder = new Base64Decoder() ;
dec.decode(
"pQEAAACkCwBjb3B5Q2hhbm5lbKAMbmFtZXNwYWNlAGpwLnphaGlyAKAMdmVuZG9yAHphaGlyAKAI" +
"dmVyc2lvbgABAKEBAgAADF9PdXRDb29yZACjAARzcmMAoQIEAQAPZHN0AKEBCAGACGRzdENoYW5u" +
"ZWwAoghtYXhWYWx1ZQADAKIIbWluVmFsdWUAAACiCGRlZmF1bHRWYWx1ZQAAAKIMZGVzY3JpcHRp" +
"b24AMDpDIDE6TSAyOlkgMzpLAKEBDQGABGFscGhhAKINZGVmYXVsdFZhbHVlAAEAMAIA8QAAEAAd" +
"AwDzAgAbADIAACAAAAAAMgGAIAAAAAAoAYCAAYCAAB0BgBAAgAAANAAAAAGAwAAyAAAQP4AAAB0C" +
"AIAAAMAAAgIAgAMAAAAdAAAgAgAAADIDAIAAAAAAMgMAQAAAAAAyAwAgAAAAAB0DAEAAAIAAHQMA" +
"IAAAgAA1AAAAAAAAADIBgCABAAAAKAGAgAGAgAAdAoCAAIAAADQAAAACgAAAMgAAED+AAAAdAgCA" +
"AADAAAICAIADAEAAHQAAIAIAAAAyAwCAAAAAADIDAEAAAAAAMgMAIAAAAAAdAwCAAACAAB0DACAA" +
"AIAANQAAAAAAAAAyAYAgAgAAACgBgIABgIAAHQKAQACAAAA0AAAAAoBAADIAABA/gAAAHQIAgAAA" +
"wAACAgCAAwCAAB0AACACAAAAMgMAgAAAAAAyAwBAAAAAADIDACAAAAAAHQMAgAAAgAAdAwBAAACA" +
"ADUAAAAAAAAAMgGAIAMAAAAoAYCAAYCAAB0CgCAAgAAANAAAAAKAgAAyAAAQP4AAAB0CAIAAAMAA" +
"AgIAgAMAAAAdAAAQAgAAADICAIA/gAAAHQIAQAIAAAACAgBAAwBAAB0CAIACAEAAMgIAQD+AAAAd" +
"AgAgAgBAAAICACADAIAAHQIAQAIAgAAdAgAgAgAAAAkCACACAEAAHQIAEAAAwAAJAgAQAgCAAB0A" +
"ACACAMAAMgIAID+AAAAdAgAQAgCAAAICABAAAIAAHQQAgAIAwAAyAgAgP4AAAB0CABACAIAAAgIA" +
"EAAAgAAdBABAAgDAADICACA/gAAAHQIAEAIAgAACAgAQAACAAB0EACACAMAAHQMA4gQAGAA2AAAA" +
"AAAAADYAAAAAAAAANgAAAAAAAAA2AAAAAAAAADIBgCABAAAAKAGAQAGAgAAdAYAQAIAAADQAAAAB" +
"gMAAHQMAEAAAgAA2AAAAAAAAAB0BAPMDABsA" );
code = dec.toByteArray();
dec = null;
}
public static const C:int = 0;
public static const M:int = 1;
public static const Y:int = 2;
public static const K:int = 3;
public function ChannelCMYK( bitmapData:BitmapData, channel:int, alpha:Boolean = true ){
super( code );
src( bitmapData, bitmapData.width, bitmapData.height );
dstChannel = [ channel ];
//this.alpha = [alpha];
}
public function get alpha():Array{
return data[ "alpha" ].value;
}
public function set alpha( value:Array ):void{
data[ "alpha" ].value = value;
}
public function get dstChannel():Array{
return data[ "dstChannel" ].value;
}
public function set dstChannel( value:Array ):void{
data[ "dstChannel" ].value = value;
}
public function src( input:*, width:int, height:int):void{
data[ "src" ].input = input;
data[ "src" ].width = width;
data[ "src" ].height = height;
}
public function get srcChannels():int{
return data[ "src" ].channels;
}
}