notice: Flash editor updated! Join the development! Thanks to MiniBuilder


embed

FAVORITE BY
:
:
load&save
:
クリスマスの次はこれ!
:
:
:
:
FP10PNGEncloadsavepicturesgrabar fotos png
:
:
保存する
:
fp10load&savesave and load a png from flash
:
savephoto up save
:
:
:
みかんジェネレーター
:
すごいなぁ
:
FP10FileReference
:
load and save image
:
みかんだいすき
:
nice Mikan !
:
流行のみかんを合成できる
FORKED
  1. // forked from Saqoosha's Mikan
  2. // 1. LOAD で適当な画像をロード。
  3. // 2. みかんをドラッグで移動とか。Shift 押しながらで拡大縮小。
  4. // 3. SAVE で保存。
  5. package {
  6.     
  7.     import flash.display.Sprite;
  8.     
  9.     import org.libspark.thread.EnterFrameThreadExecutor;
  10.     import org.libspark.thread.Thread;
  11.     [SWF(width=465, height=465, backgroundColor=0xffffff, frameRate=60)]
  12.     public class Mikan extends Sprite {
  13.         
  14.         public function Mikan() {
  15.             Thread.initialize(new EnterFrameThreadExecutor());
  16.             new MainThread(this).start();
  17.         }
  18.     }
  19. }
  20. import flash.display.Bitmap;
  21. import flash.display.BitmapData;
  22. import flash.display.DisplayObject;
  23. import flash.display.Graphics;
  24. import flash.display.InteractiveObject;
  25. import flash.display.Loader;
  26. import flash.display.Shape;
  27. import flash.display.SimpleButton;
  28. import flash.display.Sprite;
  29. import flash.events.Event;
  30. import flash.events.MouseEvent;
  31. import flash.geom.Matrix;
  32. import flash.geom.Point;
  33. import flash.geom.Rectangle;
  34. import flash.net.FileReference;
  35. import flash.net.FileReferenceList;
  36. import flash.net.URLRequest;
  37. import flash.system.Security;
  38. import flash.text.TextField;
  39. import flash.text.TextFieldAutoSize;
  40. import flash.text.TextFormat;
  41. import flash.text.TextFormatAlign;
  42. import flash.utils.ByteArray;
  43. import org.libspark.thread.Thread;
  44. class MainThread extends Thread {
  45.     
  46.     public static const PROXY:String = "http://5ivestar.org/proxy/";
  47.     public static const CROSSDOMAIN:String = "http://5ivestar.org/proxy/crossdomain.xml";
  48.         
  49.     private var _base:Sprite;
  50.     private var _loadButton:Button;
  51.     private var _saveButton:Button;
  52.     private var _mikan:MikanImage;
  53.     private var _original:Loader;
  54.     private var _guide:Guide;
  55.     
  56.     public function MainThread(base:Sprite) {
  57.         this._base = base;
  58.         this._loadButton = this._base.addChild(new Button('LOAD'60)) as Button;
  59.         this._loadButton.x = this._loadButton.y = 1;
  60.         this._saveButton = this._base.addChild(new Button('SAVE'60)) as Button;
  61.         this._saveButton.x = 1;
  62.         this._saveButton.y = this._loadButton.height + 2;
  63.         this._guide = this._base.addChild(new Guide()) as Guide;
  64.         this._guide.x = this._guide.y = (465 - 256) >> 1;
  65.         Security.loadPolicyFile(CROSSDOMAIN);
  66.     }
  67.     
  68.     protected override function run():void {
  69.         this._mikan = this._base.addChildAt(new MikanImage(), 0as MikanImage;
  70.         event(this._mikan, Event.COMPLETE, this._mikanLoaded);
  71.         this._mikan.init();
  72.     }
  73.     
  74.     private function _mikanLoaded(e:Event):void {
  75.         this._mikan.scaleX = this._mikan.scaleY = 256 * 0.4 / this._mikan.width;
  76.         this._mikan.x = this._guide.x + 128;
  77.         this._mikan.y = this._guide.y + this._mikan.height / 2 + 10;
  78.         
  79.         this._event();
  80.         trace("click");
  81.     }
  82.     
  83.     private function _event():void {
  84.         event(this._loadButton, MouseEvent.CLICK, this._loadImage);
  85.         event(this._saveButton, MouseEvent.CLICK, this._saveImage);
  86.         event(this._mikan, MouseEvent.MOUSE_DOWN, this._dragStart);
  87.     trace("click");
  88.     }
  89.     
  90.     
  91.     // load image
  92.     private function _loadImage(e:MouseEvent):void {
  93.         var file:FileReference = new FileReference();
  94.         event(file, Event.SELECT, this._loadFileSelected);
  95.         file.browse();
  96.         trace("click1");
  97.     }
  98.     
  99.     private function _loadFileSelected(e:Event):void {
  100.         var file:FileReference = FileReference(e.target);
  101.         event(file, Event.COMPLETE, this._fileLoaded);
  102.         file.load();
  103.         trace("click2");
  104.     }
  105.     
  106.     private function _fileLoaded(e:Event):void {
  107.         if (this._original) {
  108.             this._original.parent.removeChild(this._original);
  109.             this._original.unload();
  110.         }
  111.         this._original = this._base.addChildAt(new Loader(), 0as Loader;
  112.         this._original.loadBytes(FileReference(e.target).data);
  113.         event(this._original.contentLoaderInfo, Event.COMPLETE, this._imageLoaded);
  114.     }
  115.     
  116.     private function _imageLoaded(e:Event):void {
  117.         var a:Number = 256 / Math.max(this._original.width, this._original.height);
  118.         this._original.scaleX = this._original.scaleY = a;
  119.         this._original.x = this._guide.x + (256 - this._original.width) / 2;
  120.         this._original.y = this._guide.y + (256 - this._original.height) / 2;
  121.         Bitmap(this._original.content).smoothing = true;
  122.         this._event();
  123.         trace("click3");
  124.     }
  125.     
  126.     
  127.     // manipulate mikan
  128.     private var _startScale:Number;
  129.     private var _startPoint:Point = new Point();
  130.     private function _dragStart(e:MouseEvent):void {
  131.         var sp:Sprite = Sprite(e.target);
  132.         if (e.shiftKey) {
  133.             this._startScale = sp.scaleX;
  134.             this._startPoint.x = this._base.mouseX;
  135.             this._startPoint.y = this._base.mouseY;
  136.             event(this._base.stage, MouseEvent.MOUSE_MOVE, this._scaleObject);
  137.             event(this._base.stage, MouseEvent.MOUSE_UP, this._scaleEnd);
  138.         } else {
  139.             sp.startDrag(false);
  140.             event(sp, MouseEvent.MOUSE_UP, this._dragEnd);
  141.         }
  142.     }
  143.     
  144.     private function _scaleObject(e:MouseEvent):void {
  145.         var newScale:Number = this._startScale * (this._base.mouseX - this._mikan.x) / (this._startPoint.x - this._mikan.x);
  146.         this._mikan.scaleX = this._mikan.scaleY = newScale;
  147.         event(this._base.stage, MouseEvent.MOUSE_MOVE, this._scaleObject);
  148.         event(this._base.stage, MouseEvent.MOUSE_UP, this._scaleEnd);
  149.     }
  150.     
  151.     private function _scaleEnd(e:MouseEvent):void {
  152.         this._event();
  153.     }
  154.     
  155.     private function _dragEnd(e:MouseEvent):void {
  156.         Sprite(e.target).stopDrag();
  157.         this._event();
  158.     }
  159.     
  160.     
  161.     // save image
  162.     private function _saveImage(e:Event):void {
  163.         var raw:BitmapData = new BitmapData(256256true, 0x0);
  164.         this._guide.visible = false;
  165.         raw.draw(this._base, new Matrix(1001, -this._guide.x, -this._guide.y), nullnullnulltrue);
  166.         this._guide.visible = true;
  167.         var png:ByteArray = PNGEnc.encode(raw);
  168.         raw.dispose();
  169.         var file:FileReference = new FileReference();
  170.         event(file, Event.SELECT, this._saveFileSelected);
  171.         file.save(png, 'mikaned.png');
  172.     }
  173.     
  174.     private function _saveFileSelected(e:Event):void {
  175.         this._event();
  176.     }
  177. }
  178. class MikanImage extends Sprite {
  179.     
  180.     private var _mikan:Loader;
  181.     
  182.     public function MikanImage() {
  183.         this.buttonMode = true;
  184.         this.useHandCursor = true;
  185.         this.mouseChildren = false;
  186.     }
  187.     
  188.     public function init():void {
  189.         this._mikan = this.addChild(new Loader()) as Loader;
  190.         this._mikan.contentLoaderInfo.addEventListener(Event.COMPLETE, this._mikanLoaded);
  191.         this._mikan.load(new URLRequest(MainThread.PROXY + 'http://level0.kayac.com/src/doke/mikan.png'));
  192.     }
  193.     
  194.     private function _mikanLoaded(e:Event):void {
  195.         this._mikan.x = -this._mikan.width / 2;
  196.         this._mikan.y = -this._mikan.height / 2;
  197.         this.dispatchEvent(new Event(Event.COMPLETE));
  198.     }
  199. }
  200. class Button extends SimpleButton {
  201.     
  202.     public function Button(label:String, width:int = 0):void {
  203.         var up:Sprite = _buildImage(label, 0x0, width);
  204.         var over:Sprite = _buildImage(label, 0x333333, width);
  205.         var down:Sprite = _buildImage(label, 0x333333, width);
  206.         down.y = 1;
  207.         super(up, over, down, up);
  208.     }
  209.     
  210.     private static function _buildImage(label:String, color:int, width:int = 0):Sprite {
  211.         var text:TextField = new TextField();
  212.         text.defaultTextFormat = new TextFormat('Verdana'10, 0xffffff, truenullnullnullnull, TextFormatAlign.CENTER);
  213.         text.autoSize = TextFieldAutoSize.LEFT
  214.         text.selectable = false;
  215.         text.text = label;
  216.         text.x = (width - text.width) >> 1;
  217.         text.y = 5;
  218.         var base:Shape = new Shape();
  219.         var g:Graphics = base.graphics;
  220.         g.beginFill(color);
  221.         g.drawRect(00, width, text.height + 10);
  222.         g.endFill();
  223.         var sp:Sprite = new Sprite();
  224.         sp.addChild(base);
  225.         sp.addChild(text);
  226.         return sp;
  227.     }
  228. }
  229. class Guide extends Shape {
  230.     
  231.     public function Guide() {
  232.         var g:Graphics = this.graphics;
  233.         g.lineStyle(1, 0x0, 0.3true);
  234.         g.drawRect(00255255);
  235.     }
  236. }
  237. // http://www.5etdemi.com/blog/archives/2006/12/as3-png-encoder-faster-better/
  238. class PNGEnc {
  239.     
  240.     public static function encode(img:BitmapData, type:uint = 0):ByteArray {
  241.         
  242.         // Create output byte array
  243.         var png:ByteArray = new ByteArray();
  244.         // Write PNG signature
  245.         png.writeUnsignedInt(0x89504e47);
  246.         png.writeUnsignedInt(0x0D0A1A0A);
  247.         // Build IHDR chunk
  248.         var IHDR:ByteArray = new ByteArray();
  249.         IHDR.writeInt(img.width);
  250.         IHDR.writeInt(img.height);
  251.         if(img.transparent || type == 0)
  252.         {
  253.             IHDR.writeUnsignedInt(0x08060000); // 32bit RGBA
  254.         }
  255.         else
  256.         {
  257.             IHDR.writeUnsignedInt(0x08020000); //24bit RGB
  258.         }
  259.         IHDR.writeByte(0);
  260.         writeChunk(png,0x49484452,IHDR);
  261.         // Build IDAT chunk
  262.         var IDAT:ByteArray= new ByteArray();
  263.         
  264.         switch(type)
  265.         {
  266.             case 0:
  267.                 writeRaw(img, IDAT);
  268.                 break;
  269.             case 1:
  270.                 writeSub(img, IDAT);
  271.                 break;
  272.         }
  273.         
  274.         IDAT.compress();
  275.         writeChunk(png,0x49444154,IDAT);
  276.         // Build IEND chunk
  277.         writeChunk(png,0x49454E44,null);
  278.         // return PNG
  279.         
  280.         
  281.         
  282.         return png;
  283.     }
  284.     
  285.     private static function writeRaw(img:BitmapData, IDAT:ByteArray):void
  286.     {
  287.         var h:int = img.height;
  288.         var w:int = img.width;
  289.         var transparent:Boolean = img.transparent;
  290.         
  291.         for(var i:int=0;i < h;i++) {
  292.             // no filter
  293.             if ( !transparent ) {
  294.                 var subImage:ByteArray = img.getPixels(
  295.                     new Rectangle(0, i, w, 1));
  296.                 //Here we overwrite the alpha value of the first pixel
  297.                 //to be the filter 0 flag
  298.                 subImage[0] = 0;
  299.                 IDAT.writeBytes(subImage);
  300.                 //And we add a byte at the end to wrap the alpha values
  301.                 IDAT.writeByte(0xff);
  302.             } else {
  303.                 IDAT.writeByte(0);
  304.                 var p:uint;
  305.                 for(var j:int=0;j < w;j++) {
  306.                     p = img.getPixel32(j,i);
  307.                     IDAT.writeUnsignedInt(
  308.                         uint(((p&0xFFFFFF) << 8)|
  309.                         (p>>>24)));
  310.                 }
  311.             }
  312.         }
  313.     }
  314.     
  315.     private static function writeSub(img:BitmapData, IDAT:ByteArray):void
  316.     {
  317.         var r1:uint;
  318.         var g1:uint;
  319.         var b1:uint;
  320.         var a1:uint;
  321.         
  322.         var r2:uint;
  323.         var g2:uint;
  324.         var b2:uint;
  325.         var a2:uint;
  326.         
  327.         var r3:uint;
  328.         var g3:uint;
  329.         var b3:uint;
  330.         var a3:uint;
  331.         
  332.         var p:uint;
  333.         var h:int = img.height;
  334.         var w:int = img.width;
  335.         
  336.         for(var i:int=0;i < h;i++) {
  337.             // no filter
  338.             IDAT.writeByte(1);
  339.             if ( !img.transparent ) {
  340.                 r1 = 0;
  341.                 g1 = 0;
  342.                 b1 = 0;
  343.                 a1 = 0xff;
  344.                 for(var j:int=0;j < w;j++) {
  345.                     p = img.getPixel(j,i);
  346.                     
  347.                     r2 = p >> 16 & 0xff;
  348.                     g2 = p >> 8  & 0xff;
  349.                     b2 = p & 0xff;
  350.                     
  351.                     r3 = (r2 - r1 + 256) & 0xff;
  352.                     g3 = (g2 - g1 + 256) & 0xff;
  353.                     b3 = (b2 - b1 + 256) & 0xff;
  354.                     
  355.                     IDAT.writeByte(r3);
  356.                     IDAT.writeByte(g3);
  357.                     IDAT.writeByte(b3);
  358.                     
  359.                     r1 = r2;
  360.                     g1 = g2;
  361.                     b1 = b2;
  362.                     a1 = 0;
  363.                 }
  364.             } else {
  365.                 r1 = 0;
  366.                 g1 = 0;
  367.                 b1 = 0;
  368.                 a1 = 0;
  369.                 for(j=0;j < w;j++) {
  370.                     p = img.getPixel32(j,i);
  371.                     
  372.                     a2 = p >> 24 & 0xff;
  373.                     r2 = p >> 16 & 0xff;
  374.                     g2 = p >> 8  & 0xff;
  375.                     b2 = p & 0xff;
  376.                     
  377.                     r3 = (r2 - r1 + 256) & 0xff;
  378.                     g3 = (g2 - g1 + 256) & 0xff;
  379.                     b3 = (b2 - b1 + 256) & 0xff;
  380.                     a3 = (a2 - a1 + 256) & 0xff;
  381.                     
  382.                     IDAT.writeByte(r3);
  383.                     IDAT.writeByte(g3);
  384.                     IDAT.writeByte(b3);
  385.                     IDAT.writeByte(a3);
  386.                     
  387.                     r1 = r2;
  388.                     g1 = g2;
  389.                     b1 = b2;
  390.                     a1 = a2;
  391.                 }
  392.             }
  393.         }
  394.     }
  395.     private static var crcTable:Array;
  396.     private static var crcTableComputed:Boolean = false;
  397.     private static function writeChunk(png:ByteArray, 
  398.             type:uint, data:ByteArray):void {
  399.         var c:uint;
  400.         if (!crcTableComputed) {
  401.             crcTableComputed = true;
  402.             crcTable = [];
  403.             for (var n:uint = 0; n < 256; n++) {
  404.                 c = n;
  405.                 for (var k:uint = 0; k < 8; k++) {
  406.                     if (c & 1) {
  407.                         c = uint(uint(0xedb88320) ^ 
  408.                             uint(c >>> 1));
  409.                     } else {
  410.                         c = uint(c >>> 1);
  411.                     }
  412.                 }
  413.                 crcTable[n] = c;
  414.             }
  415.         }
  416.         var len:uint = 0;
  417.         if (data != null) {
  418.             len = data.length;
  419.         }
  420.         png.writeUnsignedInt(len);
  421.         var p:uint = png.position;
  422.         png.writeUnsignedInt(type);
  423.         if ( data != null ) {
  424.             png.writeBytes(data);
  425.         }
  426.         var e:uint = png.position;
  427.         png.position = p;
  428.         c = 0xffffffff;
  429.         for (var i:int = 0; i < (e-p); i++) {
  430.             c = uint(crcTable[
  431.                 (c ^ png.readUnsignedByte()) & 
  432.                 0xff] ^ (c >>> 8));
  433.         }
  434.         c = uint(c^uint(0xffffffff));
  435.         png.position = e;
  436.         png.writeUnsignedInt(c);
  437.     }
  438. }
noswf
  1. // forked from Saqoosha's Mikan
  2. // 1. LOAD で適当な画像をロード。
  3. // 2. みかんをドラッグで移動とか。Shift 押しながらで拡大縮小。
  4. // 3. SAVE で保存。
  5. package {
  6.     
  7.     import flash.display.Sprite;
  8.     
  9.     import org.libspark.thread.EnterFrameThreadExecutor;
  10.     import org.libspark.thread.Thread;
  11.     [SWF(width=465, height=465, backgroundColor=0xffffff, frameRate=60)]
  12.     public class Mikan extends Sprite {
  13.         
  14.         public function Mikan() {
  15.             Thread.initialize(new EnterFrameThreadExecutor());
  16.             new MainThread(this).start();
  17.         }
  18.     }
  19. }
  20. import flash.display.Bitmap;
  21. import flash.display.BitmapData;
  22. import flash.display.DisplayObject;
  23. import flash.display.Graphics;
  24. import flash.display.InteractiveObject;
  25. import flash.display.Loader;
  26. import flash.display.Shape;
  27. import flash.display.SimpleButton;
  28. import flash.display.Sprite;
  29. import flash.events.Event;
  30. import flash.events.MouseEvent;
  31. import flash.geom.Matrix;
  32. import flash.geom.Point;
  33. import flash.geom.Rectangle;
  34. import flash.net.FileReference;
  35. import flash.net.FileReferenceList;
  36. import flash.net.URLRequest;
  37. import flash.system.Security;
  38. import flash.text.TextField;
  39. import flash.text.TextFieldAutoSize;
  40. import flash.text.TextFormat;
  41. import flash.text.TextFormatAlign;
  42. import flash.utils.ByteArray;
  43. import org.libspark.thread.Thread;
  44. class MainThread extends Thread {
  45.     
  46.     public static const PROXY:String = "http://www.planet-ape.net/wonderfl/";
  47.     public static const CROSSDOMAIN:String = "http://www.planet-ape.net/wonderfl/crossdomain.xml";
  48.         
  49.     private var _base:Sprite;
  50.     private var _loadButton:Button;
  51.     private var _saveButton:Button;
  52.     private var _mikan:MikanImage;
  53.     private var _original:Loader;
  54.     private var _guide:Guide;
  55.     
  56.     public function MainThread(base:Sprite) {
  57.         this._base = base;
  58.         this._loadButton = this._base.addChild(new Button('LOAD'60)) as Button;
  59.         this._loadButton.x = this._loadButton.y = 1;
  60.         this._saveButton = this._base.addChild(new Button('SAVE'60)) as Button;
  61.         this._saveButton.x = 1;
  62.         this._saveButton.y = this._loadButton.height + 2;
  63.         this._guide = this._base.addChild(new Guide()) as Guide;
  64.         this._guide.x = this._guide.y = (465 - 256) >> 1;
  65.         Security.loadPolicyFile(CROSSDOMAIN);
  66.     }
  67.     
  68.     protected override function run():void {
  69.         this._mikan = this._base.addChildAt(new MikanImage(), 0as MikanImage;
  70.         event(this._mikan, Event.COMPLETE, this._mikanLoaded);
  71.         this._mikan.init();
  72.     }
  73.     
  74.     private function _mikanLoaded(e:Event):void {
  75.         this._mikan.scaleX = this._mikan.scaleY = 256 * 0.4 / this._mikan.width;
  76.         this._mikan.x = this._guide.x + 128;
  77.         this._mikan.y = this._guide.y + this._mikan.height / 2 + 10;
  78.         
  79.         this._event();
  80.     }
  81.     
  82.     private function _event():void {
  83.         event(this._loadButton, MouseEvent.CLICK, this._loadImage);
  84.         event(this._saveButton, MouseEvent.CLICK, this._saveImage);
  85.         event(this._mikan, MouseEvent.MOUSE_DOWN, this._dragStart);
  86.     }
  87.     
  88.     
  89.     // load image
  90.     private function _loadImage(e:MouseEvent):void {
  91.         var file:FileReference = new FileReference();
  92.         event(file, Event.SELECT, this._loadFileSelected);
  93.         file.browse();
  94.     }
  95.     
  96.     private function _loadFileSelected(e:Event):void {
  97.         var file:FileReference = FileReference(e.target);
  98.         event(file, Event.COMPLETE, this._fileLoaded);
  99.         file.load();
  100.     }
  101.     
  102.     private function _fileLoaded(e:Event):void {
  103.         if (this._original) {
  104.             this._original.parent.removeChild(this._original);
  105.             this._original.unload();
  106.         }
  107.         this._original = this._base.addChildAt(new Loader(), 0as Loader;
  108.         this._original.loadBytes(FileReference(e.target).data);
  109.         event(this._original.contentLoaderInfo, Event.COMPLETE, this._imageLoaded);
  110.     }
  111.     
  112.     private function _imageLoaded(e:Event):void {
  113.         var a:Number = 256 / Math.max(this._original.width, this._original.height);
  114.         this._original.scaleX = this._original.scaleY = a;
  115.         this._original.x = this._guide.x + (256 - this._original.width) / 2;
  116.         this._original.y = this._guide.y + (256 - this._original.height) / 2;
  117.         Bitmap(this._original.content).smoothing = true;
  118.         this._event();
  119.     }
  120.     
  121.     
  122.     // manipulate mikan
  123.     private var _startScale:Number;
  124.     private var _startPoint:Point = new Point();
  125.     private function _dragStart(e:MouseEvent):void {
  126.         var sp:Sprite = Sprite(e.target);
  127.         if (e.shiftKey) {
  128.             this._startScale = sp.scaleX;
  129.             this._startPoint.x = this._base.mouseX;
  130.             this._startPoint.y = this._base.mouseY;
  131.             event(this._base.stage, MouseEvent.MOUSE_MOVE, this._scaleObject);
  132.             event(this._base.stage, MouseEvent.MOUSE_UP, this._scaleEnd);
  133.         } else {
  134.             sp.startDrag(false);
  135.             event(sp, MouseEvent.MOUSE_UP, this._dragEnd);
  136.         }
  137.     }
  138.     
  139.     private function _scaleObject(e:MouseEvent):void {
  140.         var newScale:Number = this._startScale * (this._base.mouseX - this._mikan.x) / (this._startPoint.x - this._mikan.x);
  141.         this._mikan.scaleX = this._mikan.scaleY = newScale;
  142.         event(this._base.stage, MouseEvent.MOUSE_MOVE, this._scaleObject);
  143.         event(this._base.stage, MouseEvent.MOUSE_UP, this._scaleEnd);
  144.     }
  145.     
  146.     private function _scaleEnd(e:MouseEvent):void {
  147.         this._event();
  148.     }
  149.     
  150.     private function _dragEnd(e:MouseEvent):void {
  151.         Sprite(e.target).stopDrag();
  152.         this._event();
  153.     }
  154.     
  155.     
  156.     // save image
  157.     private function _saveImage(e:Event):void {
  158.         var raw:BitmapData = new BitmapData(256256true, 0x0);
  159.         this._guide.visible = false;
  160.         raw.draw(this._base, new Matrix(1001, -this._guide.x, -this._guide.y), nullnullnulltrue);
  161.         this._guide.visible = true;
  162.         var png:ByteArray = PNGEnc.encode(raw);
  163.         raw.dispose();
  164.         var file:FileReference = new FileReference();
  165.         event(file, Event.SELECT, this._saveFileSelected);
  166.         file.save(png, 'mikaned.png');
  167.     }
  168.     
  169.     private function _saveFileSelected(e:Event):void {
  170.         this._event();
  171.     }
  172. }
  173. class MikanImage extends Sprite {
  174.     
  175.     private var _mikan:Loader;
  176.     
  177.     public function MikanImage() {
  178.         this.buttonMode = true;
  179.         this.useHandCursor = true;
  180.         this.mouseChildren = false;
  181.     }
  182.     
  183.     public function init():void {
  184.         this._mikan = this.addChild(new Loader()) as Loader;
  185.         this._mikan.contentLoaderInfo.addEventListener(Event.COMPLETE, this._mikanLoaded);
  186. //        this._mikan.load(new URLRequest(MainThread.PROXY + 'http://level0.kayac.com/src/doke/mikan.png'));
  187.         this._mikan.load(new URLRequest('http://www.planet-ape.net/wonderfl/santa_shadow.png'));
  188.     }
  189.     
  190.     private function _mikanLoaded(e:Event):void {
  191.         this._mikan.x = -this._mikan.width / 2;
  192.         this._mikan.y = -this._mikan.height / 2;
  193.         this.dispatchEvent(new Event(Event.COMPLETE));
  194.     }
  195. }
  196. class Button extends SimpleButton {
  197.     
  198.     public function Button(label:String, width:int = 0):void {
  199.         var up:Sprite = _buildImage(label, 0x0, width);
  200.         var over:Sprite = _buildImage(label, 0x333333, width);
  201.         var down:Sprite = _buildImage(label, 0x333333, width);
  202.         down.y = 1;
  203.         super(up, over, down, up);
  204.     }
  205.     
  206.     private static function _buildImage(label:String, color:int, width:int = 0):Sprite {
  207.         var text:TextField = new TextField();
  208.         text.defaultTextFormat = new TextFormat('Verdana'10, 0xffffff, truenullnullnullnull, TextFormatAlign.CENTER);
  209.         text.autoSize = TextFieldAutoSize.LEFT
  210.         text.selectable = false;
  211.         text.text = label;
  212.         text.x = (width - text.width) >> 1;
  213.         text.y = 5;
  214.         var base:Shape = new Shape();
  215.         var g:Graphics = base.graphics;
  216.         g.beginFill(color);
  217.         g.drawRect(00, width, text.height + 10);
  218.         g.endFill();
  219.         var sp:Sprite = new Sprite();
  220.         sp.addChild(base);
  221.         sp.addChild(text);
  222.         return sp;
  223.     }
  224. }
  225. class Guide extends Shape {
  226.     
  227.     public function Guide() {
  228.         var g:Graphics = this.graphics;
  229.         g.lineStyle(1, 0x0, 0.3true);
  230.         g.drawRect(00255255);
  231.     }
  232. }
  233. // http://www.5etdemi.com/blog/archives/2006/12/as3-png-encoder-faster-better/
  234. class PNGEnc {
  235.     
  236.     public static function encode(img:BitmapData, type:uint = 0):ByteArray {
  237.         
  238.         // Create output byte array
  239.         var png:ByteArray = new ByteArray();
  240.         // Write PNG signature
  241.         png.writeUnsignedInt(0x89504e47);
  242.         png.writeUnsignedInt(0x0D0A1A0A);
  243.         // Build IHDR chunk
  244.         var IHDR:ByteArray = new ByteArray();
  245.         IHDR.writeInt(img.width);
  246.         IHDR.writeInt(img.height);
  247.         if(img.transparent || type == 0)
  248.         {
  249.             IHDR.writeUnsignedInt(0x08060000); // 32bit RGBA
  250.         }
  251.         else
  252.         {
  253.             IHDR.writeUnsignedInt(0x08020000); //24bit RGB
  254.         }
  255.         IHDR.writeByte(0);
  256.         writeChunk(png,0x49484452,IHDR);
  257.         // Build IDAT chunk
  258.         var IDAT:ByteArray= new ByteArray();
  259.         
  260.         switch(type)
  261.         {
  262.             case 0:
  263.                 writeRaw(img, IDAT);
  264.                 break;
  265.             case 1:
  266.                 writeSub(img, IDAT);
  267.                 break;
  268.         }
  269.         
  270.         IDAT.compress();
  271.         writeChunk(png,0x49444154,IDAT);
  272.         // Build IEND chunk
  273.         writeChunk(png,0x49454E44,null);
  274.         // return PNG
  275.         
  276.         
  277.         
  278.         return png;
  279.     }
  280.     
  281.     private static function writeRaw(img:BitmapData, IDAT:ByteArray):void
  282.     {
  283.         var h:int = img.height;
  284.         var w:int = img.width;
  285.         var transparent:Boolean = img.transparent;
  286.         
  287.         for(var i:int=0;i < h;i++) {
  288.             // no filter
  289.             if ( !transparent ) {
  290.                 var subImage:ByteArray = img.getPixels(
  291.                     new Rectangle(0, i, w, 1));
  292.                 //Here we overwrite the alpha value of the first pixel
  293.                 //to be the filter 0 flag
  294.                 subImage[0] = 0;
  295.                 IDAT.writeBytes(subImage);
  296.                 //And we add a byte at the end to wrap the alpha values
  297.                 IDAT.writeByte(0xff);
  298.             } else {
  299.                 IDAT.writeByte(0);
  300.                 var p:uint;
  301.                 for(var j:int=0;j < w;j++) {
  302.                     p = img.getPixel32(j,i);
  303.                     IDAT.writeUnsignedInt(
  304.                         uint(((p&0xFFFFFF) << 8)|
  305.                         (p>>>24)));
  306.                 }
  307.             }
  308.         }
  309.     }
  310.     
  311.     private static function writeSub(img:BitmapData, IDAT:ByteArray):void
  312.     {
  313.         var r1:uint;
  314.         var g1:uint;
  315.         var b1:uint;
  316.         var a1:uint;
  317.         
  318.         var r2:uint;
  319.         var g2:uint;
  320.         var b2:uint;
  321.         var a2:uint;
  322.         
  323.         var r3:uint;
  324.         var g3:uint;
  325.         var b3:uint;
  326.         var a3:uint;
  327.         
  328.         var p:uint;
  329.         var h:int = img.height;
  330.         var w:int = img.width;
  331.         
  332.         for(var i:int=0;i < h;i++) {
  333.             // no filter
  334.             IDAT.writeByte(1);
  335.             if ( !img.transparent ) {
  336.                 r1 = 0;
  337.                 g1 = 0;
  338.                 b1 = 0;
  339.                 a1 = 0xff;
  340.                 for(var j:int=0;j < w;j++) {
  341.                     p = img.getPixel(j,i);
  342.                     
  343.                     r2 = p >> 16 & 0xff;
  344.                     g2 = p >> 8  & 0xff;
  345.                     b2 = p & 0xff;
  346.                     
  347.                     r3 = (r2 - r1 + 256) & 0xff;
  348.                     g3 = (g2 - g1 + 256) & 0xff;
  349.                     b3 = (b2 - b1 + 256) & 0xff;
  350.                     
  351.                     IDAT.writeByte(r3);
  352.                     IDAT.writeByte(g3);
  353.                     IDAT.writeByte(b3);
  354.                     
  355.                     r1 = r2;
  356.                     g1 = g2;
  357.                     b1 = b2;
  358.                     a1 = 0;
  359.                 }
  360.             } else {
  361.                 r1 = 0;
  362.                 g1 = 0;
  363.                 b1 = 0;
  364.                 a1 = 0;
  365.                 for(j=0;j < w;j++) {
  366.                     p = img.getPixel32(j,i);
  367.                     
  368.                     a2 = p >> 24 & 0xff;
  369.                     r2 = p >> 16 & 0xff;
  370.                     g2 = p >> 8  & 0xff;
  371.                     b2 = p & 0xff;
  372.                     
  373.                     r3 = (r2 - r1 + 256) & 0xff;
  374.                     g3 = (g2 - g1 + 256) & 0xff;
  375.                     b3 = (b2 - b1 + 256) & 0xff;
  376.                     a3 = (a2 - a1 + 256) & 0xff;
  377.                     
  378.                     IDAT.writeByte(r3);
  379.                     IDAT.writeByte(g3);
  380.                     IDAT.writeByte(b3);
  381.                     IDAT.writeByte(a3);
  382.                     
  383.                     r1 = r2;
  384.                     g1 = g2;
  385.                     b1 = b2;
  386.                     a1 = a2;
  387.                 }
  388.             }
  389.         }
  390.     }
  391.     private static var crcTable:Array;
  392.     private static var crcTableComputed:Boolean = false;
  393.     private static function writeChunk(png:ByteArray, 
  394.             type:uint, data:ByteArray):void {
  395.         var c:uint;
  396.         if (!crcTableComputed) {
  397.             crcTableComputed = true;
  398.             crcTable = [];
  399.             for (var n:uint = 0; n < 256; n++) {
  400.                 c = n;
  401.                 for (var k:uint = 0; k < 8; k++) {
  402.                     if (c & 1) {
  403.                         c = uint(uint(0xedb88320) ^ 
  404.                             uint(c >>> 1));
  405.                     } else {
  406.                         c = uint(c >>> 1);
  407.                     }
  408.                 }
  409.                 crcTable[n] = c;
  410.             }
  411.         }
  412.         var len:uint = 0;
  413.         if (data != null) {
  414.             len = data.length;
  415.         }
  416.         png.writeUnsignedInt(len);
  417.         var p:uint = png.position;
  418.         png.writeUnsignedInt(type);
  419.         if ( data != null ) {
  420.             png.writeBytes(data);
  421.         }
  422.         var e:uint = png.position;
  423.         png.position = p;
  424.         c = 0xffffffff;
  425.         for (var i:int = 0; i < (e-p); i++) {
  426.             c = uint(crcTable[
  427.                 (c ^ png.readUnsignedByte()) & 
  428.                 0xff] ^ (c >>> 8));
  429.         }
  430.         c = uint(c^uint(0xffffffff));
  431.         png.position = e;
  432.         png.writeUnsignedInt(c);
  433.     }
  434. }
noswf
  1. // forked from Saqoosha's Mikan
  2. // 1. LOAD で適当な画像をロード。
  3. // 2. みかんをドラッグで移動とか。Shift 押しながらで拡大縮小。
  4. // 3. SAVE で保存。
  5. package {
  6.     
  7.     import flash.display.Sprite;
  8.     
  9.     import org.libspark.thread.EnterFrameThreadExecutor;
  10.     import org.libspark.thread.Thread;
  11.     [SWF(width=465, height=465, backgroundColor=0xffffff, frameRate=60)]
  12.     public class Mikan extends Sprite {
  13.         
  14.         public function Mikan() {
  15.             Thread.initialize(new EnterFrameThreadExecutor());
  16.             new MainThread(this).start();
  17.         }
  18.     }
  19. }
  20. import flash.display.Bitmap;
  21. import flash.display.BitmapData;
  22. import flash.display.DisplayObject;
  23. import flash.display.Graphics;
  24. import flash.display.InteractiveObject;
  25. import flash.display.Loader;
  26. import flash.display.Shape;
  27. import flash.display.SimpleButton;
  28. import flash.display.Sprite;
  29. import flash.events.Event;
  30. import flash.events.MouseEvent;
  31. import flash.geom.Matrix;
  32. import flash.geom.Point;
  33. import flash.geom.Rectangle;
  34. import flash.net.FileReference;
  35. import flash.net.FileReferenceList;
  36. import flash.net.URLRequest;
  37. import flash.system.Security;
  38. import flash.text.TextField;
  39. import flash.text.TextFieldAutoSize;
  40. import flash.text.TextFormat;
  41. import flash.text.TextFormatAlign;
  42. import flash.utils.ByteArray;
  43. import org.libspark.thread.Thread;
  44. class MainThread extends Thread {
  45.     
  46.     public static const PROXY:String = "http://5ivestar.org/proxy/";
  47.     public static const CROSSDOMAIN:String = "http://5ivestar.org/proxy/crossdomain.xml";
  48.         
  49.     private var _base:Sprite;
  50.     private var _loadButton:Button;
  51.     private var _saveButton:Button;
  52.     private var _mikan:MikanImage;
  53.     private var _original:Loader;
  54.     private var _guide:Guide;
  55.     
  56.     public function MainThread(base:Sprite) {
  57.         this._base = base;
  58.         this._loadButton = this._base.addChild(new Button('LOAD'60)) as Button;
  59.         this._loadButton.x = this._loadButton.y = 1;
  60.         this._saveButton = this._base.addChild(new Button('SAVE'60)) as Button;
  61.         this._saveButton.x = 1;
  62.         this._saveButton.y = this._loadButton.height + 2;
  63.         this._guide = this._base.addChild(new Guide()) as Guide;
  64.         this._guide.x = this._guide.y = (465 - 256) >> 1;
  65.         Security.loadPolicyFile(CROSSDOMAIN);
  66.     }
  67.     
  68.     protected override function run():void {
  69.         this._mikan = this._base.addChildAt(new MikanImage(), 0as MikanImage;
  70.         event(this._mikan, Event.COMPLETE, this._mikanLoaded);
  71.         this._mikan.init();
  72.     }
  73.     
  74.     private function _mikanLoaded(e:Event):void {
  75.         this._mikan.scaleX = this._mikan.scaleY = 256 * 0.4 / this._mikan.width;
  76.         this._mikan.x = this._guide.x + 128;
  77.         this._mikan.y = this._guide.y + this._mikan.height / 2 + 10;
  78.         
  79.         this._event();
  80.     }
  81.     
  82.     private function _event():void {
  83.         event(this._loadButton, MouseEvent.CLICK, this._loadImage);
  84.         event(this._saveButton, MouseEvent.CLICK, this._saveImage);
  85.         event(this._mikan, MouseEvent.MOUSE_DOWN, this._dragStart);
  86.     }
  87.     
  88.     
  89.     // load image
  90.     private function _loadImage(e:MouseEvent):void {
  91.         var file:FileReference = new FileReference();
  92.         event(file, Event.SELECT, this._loadFileSelected);
  93.         file.browse();
  94.     }
  95.     
  96.     private function _loadFileSelected(e:Event):void {
  97.         var file:FileReference = FileReference(e.target);
  98.         event(file, Event.COMPLETE, this._fileLoaded);
  99.         file.load();
  100.     }
  101.     
  102.     private function _fileLoaded(e:Event):void {
  103.         if (this._original) {
  104.             this._original.parent.removeChild(this._original);
  105.             this._original.unload();
  106.         }
  107.         this._original = this._base.addChildAt(new Loader(), 0as Loader;
  108.         this._original.loadBytes(FileReference(e.target).data);
  109.         event(this._original.contentLoaderInfo, Event.COMPLETE, this._imageLoaded);
  110.     }
  111.     
  112.     private function _imageLoaded(e:Event):void {
  113.         var a:Number = 256 / Math.max(this._original.width, this._original.height);
  114.         this._original.scaleX = this._original.scaleY = a;
  115.         this._original.x = this._guide.x + (256 - this._original.width) / 2;
  116.         this._original.y = this._guide.y + (256 - this._original.height) / 2;
  117.         Bitmap(this._original.content).smoothing = true;
  118.         this._event();
  119.     }
  120.     
  121.     
  122.     // manipulate mikan
  123.     private var _startScale:Number;
  124.     private var _startPoint:Point = new Point();
  125.     private function _dragStart(e:MouseEvent):void {
  126.         var sp:Sprite = Sprite(e.target);
  127.         if (e.shiftKey) {
  128.             this._startScale = sp.scaleX;
  129.             this._startPoint.x = this._base.mouseX;
  130.             this._startPoint.y = this._base.mouseY;
  131.             event(this._base.stage, MouseEvent.MOUSE_MOVE, this._scaleObject);
  132.             event(this._base.stage, MouseEvent.MOUSE_UP, this._scaleEnd);
  133.         } else {
  134.             sp.startDrag(false);
  135.             event(sp, MouseEvent.MOUSE_UP, this._dragEnd);
  136.         }
  137.     }
  138.     
  139.     private function _scaleObject(e:MouseEvent):void {
  140.         var newScale:Number = this._startScale * (this._base.mouseX - this._mikan.x) / (this._startPoint.x - this._mikan.x);
  141.         this._mikan.scaleX = this._mikan.scaleY = newScale;
  142.         event(this._base.stage, MouseEvent.MOUSE_MOVE, this._scaleObject);
  143.         event(this._base.stage, MouseEvent.MOUSE_UP, this._scaleEnd);
  144.     }
  145.     
  146.     private function _scaleEnd(e:MouseEvent):void {
  147.         this._event();
  148.     }
  149.     
  150.     private function _dragEnd(e:MouseEvent):void {
  151.         Sprite(e.target).stopDrag();
  152.         this._event();
  153.     }
  154.     
  155.     
  156.     // save image
  157.     private function _saveImage(e:Event):void {
  158.         var raw:BitmapData = new BitmapData(256256true, 0x0);
  159.         this._guide.visible = false;
  160.         raw.draw(this._base, new Matrix(1001, -this._guide.x, -this._guide.y), nullnullnulltrue);
  161.         this._guide.visible = true;
  162.         var png:ByteArray = PNGEnc.encode(raw);
  163.         raw.dispose();
  164.         var file:FileReference = new FileReference();
  165.         event(file, Event.SELECT, this._saveFileSelected);
  166.         file.save(png, 'mikaned.png');
  167.     }
  168.     
  169.     private function _saveFileSelected(e:Event):void {
  170.         this._event();
  171.     }
  172. }
  173. class MikanImage extends Sprite {
  174.     
  175.     private var _mikan:Loader;
  176.     
  177.     public function MikanImage() {
  178.         this.buttonMode = true;
  179.         this.useHandCursor = true;
  180.         this.mouseChildren = false;
  181.     }
  182.     
  183.     public function init():void {
  184.         this._mikan = this.addChild(new Loader()) as Loader;
  185.         this._mikan.contentLoaderInfo.addEventListener(Event.COMPLETE, this._mikanLoaded);
  186.         this._mikan.load(new URLRequest(MainThread.PROXY + 'http://level0.kayac.com/src/doke/mikan.png'));
  187.     }
  188.     
  189.     private function _mikanLoaded(e:Event):void {
  190.         this._mikan.x = -this._mikan.width / 2;
  191.         this._mikan.y = -this._mikan.height / 2;
  192.         this.dispatchEvent(new Event(Event.COMPLETE));
  193.     }
  194. }
  195. class Button extends SimpleButton {
  196.     
  197.     public function Button(label:String, width:int = 0):void {
  198.         var up:Sprite = _buildImage(label, 0x0, width);
  199.         var over:Sprite = _buildImage(label, 0x333333, width);
  200.         var down:Sprite = _buildImage(label, 0x333333, width);
  201.         down.y = 1;
  202.         super(up, over, down, up);
  203.     }
  204.     
  205.     private static function _buildImage(label:String, color:int, width:int = 0):Sprite {
  206.         var text:TextField = new TextField();
  207.         text.defaultTextFormat = new TextFormat('Verdana'10, 0xffffff, truenullnullnullnull, TextFormatAlign.CENTER);
  208.         text.autoSize = TextFieldAutoSize.LEFT
  209.         text.selectable = false;
  210.         text.text = label;
  211.         text.x = (width - text.width) >> 1;
  212.         text.y = 5;
  213.         var base:Shape = new Shape();
  214.         var g:Graphics = base.graphics;
  215.         g.beginFill(color);
  216.         g.drawRect(00, width, text.height + 10);
  217.         g.endFill();
  218.         var sp:Sprite = new Sprite();
  219.         sp.addChild(base);
  220.         sp.addChild(text);
  221.         return sp;
  222.     }
  223. }
  224. class Guide extends Shape {
  225.     
  226.     public function Guide() {
  227.         var g:Graphics = this.graphics;
  228.         g.lineStyle(1, 0x0, 0.3true);
  229.         g.drawRect(00255255);
  230.     }
  231. }
  232. // http://www.5etdemi.com/blog/archives/2006/12/as3-png-encoder-faster-better/
  233. class PNGEnc {
  234.     
  235.     public static function encode(img:BitmapData, type:uint = 0):ByteArray {
  236.         
  237.         // Create output byte array
  238.         var png:ByteArray = new ByteArray();
  239.         // Write PNG signature
  240.         png.writeUnsignedInt(0x89504e47);
  241.         png.writeUnsignedInt(0x0D0A1A0A);
  242.         // Build IHDR chunk
  243.         var IHDR:ByteArray = new ByteArray();
  244.         IHDR.writeInt(img.width);
  245.         IHDR.writeInt(img.height);
  246.         if(img.transparent || type == 0)
  247.         {
  248.             IHDR.writeUnsignedInt(0x08060000); // 32bit RGBA
  249.         }
  250.         else
  251.         {
  252.             IHDR.writeUnsignedInt(0x08020000); //24bit RGB
  253.         }
  254.         IHDR.writeByte(0);
  255.         writeChunk(png,0x49484452,IHDR);
  256.         // Build IDAT chunk
  257.         var IDAT:ByteArray= new ByteArray();
  258.         
  259.         switch(type)
  260.         {
  261.             case 0:
  262.                 writeRaw(img, IDAT);
  263.                 break;
  264.             case 1:
  265.                 writeSub(img, IDAT);
  266.                 break;
  267.         }
  268.         
  269.         IDAT.compress();
  270.         writeChunk(png,0x49444154,IDAT);
  271.         // Build IEND chunk
  272.         writeChunk(png,0x49454E44,null);
  273.         // return PNG
  274.         
  275.         
  276.         
  277.         return png;
  278.     }
  279.     
  280.     private static function writeRaw(img:BitmapData, IDAT:ByteArray):void
  281.     {
  282.         var h:int = img.height;
  283.         var w:int = img.width;
  284.         var transparent:Boolean = img.transparent;
  285.         
  286.         for(var i:int=0;i < h;i++) {
  287.             // no filter
  288.             if ( !transparent ) {
  289.                 var subImage:ByteArray = img.getPixels(
  290.                     new Rectangle(0, i, w, 1));
  291.                 //Here we overwrite the alpha value of the first pixel
  292.                 //to be the filter 0 flag
  293.                 subImage[0] = 0;
  294.                 IDAT.writeBytes(subImage);
  295.                 //And we add a byte at the end to wrap the alpha values
  296.                 IDAT.writeByte(0xff);
  297.             } else {
  298.                 IDAT.writeByte(0);
  299.                 var p:uint;
  300.                 for(var j:int=0;j < w;j++) {
  301.                     p = img.getPixel32(j,i);
  302.                     IDAT.writeUnsignedInt(
  303.                         uint(((p&0xFFFFFF) << 8)|
  304.                         (p>>>24)));
  305.                 }
  306.             }
  307.         }
  308.     }
  309.     
  310.     private static function writeSub(img:BitmapData, IDAT:ByteArray):void
  311.     {
  312.         var r1:uint;
  313.         var g1:uint;
  314.         var b1:uint;
  315.         var a1:uint;
  316.         
  317.         var r2:uint;
  318.         var g2:uint;
  319.         var b2:uint;
  320.         var a2:uint;
  321.         
  322.         var r3:uint;
  323.         var g3:uint;
  324.         var b3:uint;
  325.         var a3:uint;
  326.         
  327.         var p:uint;
  328.         var h:int = img.height;
  329.         var w:int = img.width;
  330.         
  331.         for(var i:int=0;i < h;i++) {
  332.             // no filter
  333.             IDAT.writeByte(1);
  334.             if ( !img.transparent ) {
  335.                 r1 = 0;
  336.                 g1 = 0;
  337.                 b1 = 0;
  338.                 a1 = 0xff;
  339.                 for(var j:int=0;j < w;j++) {
  340.                     p = img.getPixel(j,i);
  341.                     
  342.                     r2 = p >> 16 & 0xff;
  343.                     g2 = p >> 8  & 0xff;
  344.                     b2 = p & 0xff;
  345.                     
  346.                     r3 = (r2 - r1 + 256) & 0xff;
  347.                     g3 = (g2 - g1 + 256) & 0xff;
  348.                     b3 = (b2 - b1 + 256) & 0xff;
  349.                     
  350.                     IDAT.writeByte(r3);
  351.                     IDAT.writeByte(g3);
  352.                     IDAT.writeByte(b3);
  353.                     
  354.                     r1 = r2;
  355.                     g1 = g2;
  356.                     b1 = b2;
  357.                     a1 = 0;
  358.                 }
  359.             } else {
  360.                 r1 = 0;
  361.                 g1 = 0;
  362.                 b1 = 0;
  363.                 a1 = 0;
  364.                 for(j=0;j < w;j++) {
  365.                     p = img.getPixel32(j,i);
  366.                     
  367.                     a2 = p >> 24 & 0xff;
  368.                     r2 = p >> 16 & 0xff;
  369.                     g2 = p >> 8  & 0xff;
  370.                     b2 = p & 0xff;
  371.                     
  372.                     r3 = (r2 - r1 + 256) & 0xff;
  373.                     g3 = (g2 - g1 + 256) & 0xff;
  374.                     b3 = (b2 - b1 + 256) & 0xff;
  375.                     a3 = (a2 - a1 + 256) & 0xff;
  376.                     
  377.                     IDAT.writeByte(r3);
  378.                     IDAT.writeByte(g3);
  379.                     IDAT.writeByte(b3);
  380.                     IDAT.writeByte(a3);
  381.                     
  382.                     r1 = r2;
  383.                     g1 = g2;
  384.                     b1 = b2;
  385.                     a1 = a2;
  386.                 }
  387.             }
  388.         }
  389.     }
  390.     private static var crcTable:Array;
  391.     private static var crcTableComputed:Boolean = false;
  392.     private static function writeChunk(png:ByteArray, 
  393.             type:uint, data:ByteArray):void {
  394.         var c:uint;
  395.         if (!crcTableComputed) {
  396.             crcTableComputed = true;
  397.             crcTable = [];
  398.             for (var n:uint = 0; n < 256; n++) {
  399.                 c = n;
  400.                 for (var k:uint = 0; k < 8; k++) {
  401.                     if (c & 1) {
  402.                         c = uint(uint(0xedb88320) ^ 
  403.                             uint(c >>> 1));
  404.                     } else {
  405.                         c = uint(c >>> 1);
  406.                     }
  407.                 }
  408.                 crcTable[n] = c;
  409.             }
  410.         }
  411.         var len:uint = 0;
  412.         if (data != null) {
  413.             len = data.length;
  414.         }
  415.         png.writeUnsignedInt(len);
  416.         var p:uint = png.position;
  417.         png.writeUnsignedInt(type);
  418.         if ( data != null ) {
  419.             png.writeBytes(data);
  420.         }
  421.         var e:uint = png.position;
  422.         png.position = p;
  423.         c = 0xffffffff;
  424.         for (var i:int = 0; i < (e-p); i++) {
  425.             c = uint(crcTable[
  426.                 (c ^ png.readUnsignedByte()) & 
  427.                 0xff] ^ (c >>> 8));
  428.         }
  429.         c = uint(c^uint(0xffffffff));
  430.         png.position = e;
  431.         png.writeUnsignedInt(c);
  432.     }
  433. }
noswf
  1. // forked from Saqoosha's Mikan
  2. // 1. LOAD で適当な画像をロード。
  3. // 2. みかんをドラッグで移動とか。Shift 押しながらで拡大縮小。
  4. // 3. SAVE で保存。
  5. package {
  6.     
  7.     import flash.display.Sprite;
  8.     
  9.     import org.libspark.thread.EnterFrameThreadExecutor;
  10.     import org.libspark.thread.Thread;
  11.     [SWF(width=465, height=465, backgroundColor=0xffffff, frameRate=60)]
  12.     public class Mikan extends Sprite {
  13.         
  14.         public function Mikan() {
  15.             Thread.initialize(new EnterFrameThreadExecutor());
  16.             new MainThread(this).start();
  17.         }
  18.     }
  19. }
  20. import flash.display.Bitmap;
  21. import flash.display.BitmapData;
  22. import flash.display.DisplayObject;
  23. import flash.display.Graphics;
  24. import flash.display.InteractiveObject;
  25. import flash.display.Loader;
  26. import flash.display.Shape;
  27. import flash.display.SimpleButton;
  28. import flash.display.Sprite;
  29. import flash.events.Event;
  30. import flash.events.MouseEvent;
  31. import flash.geom.Matrix;
  32. import flash.geom.Point;
  33. import flash.geom.Rectangle;
  34. import flash.net.FileReference;
  35. import flash.net.FileReferenceList;
  36. import flash.net.URLRequest;
  37. import flash.system.Security;
  38. import flash.text.TextField;
  39. import flash.text.TextFieldAutoSize;
  40. import flash.text.TextFormat;
  41. import flash.text.TextFormatAlign;
  42. import flash.utils.ByteArray;
  43. import org.libspark.thread.Thread;
  44. class MainThread extends Thread {
  45.     
  46.     public static const PROXY:String = "http://5ivestar.org/proxy/";
  47.     public static const CROSSDOMAIN:String = "http://5ivestar.org/proxy/crossdomain.xml";
  48.         
  49.     private var _base:Sprite;
  50.     private var _loadButton:Button;
  51.     private var _saveButton:Button;
  52.     private var _mikan:MikanImage;
  53.     private var _original:Loader;
  54.     private var _guide:Guide;
  55.     
  56.     public function MainThread(base:Sprite) {
  57.         this._base = base;
  58.         this._loadButton = this._base.addChild(new Button('LOAD'60)) as Button;
  59.         this._loadButton.x = this._loadButton.y = 1;
  60.         this._saveButton = this._base.addChild(new Button('SAVE'60)) as Button;
  61.         this._saveButton.x = 1;
  62.         this._saveButton.y = this._loadButton.height + 2;
  63.         this._guide = this._base.addChild(new Guide()) as Guide;
  64.         this._guide.x = this._guide.y = (465 - 256) >> 1;
  65.         Security.loadPolicyFile(CROSSDOMAIN);
  66.     }
  67.     
  68.     protected override function run():void {
  69.         this._mikan = this._base.addChildAt(new MikanImage(), 0as MikanImage;
  70.         event(this._mikan, Event.COMPLETE, this._mikanLoaded);
  71.         this._mikan.init();
  72.     }
  73.     
  74.     private function _mikanLoaded(e:Event):void {
  75.         this._mikan.scaleX = this._mikan.scaleY = 256 * 0.4 / this._mikan.width;
  76.         this._mikan.x = this._guide.x + 128;
  77.         this._mikan.y = this._guide.y + this._mikan.height / 2 + 10;
  78.         
  79.         this._event();
  80.     }
  81.     
  82.     private function _event():void {
  83.         event(this._loadButton, MouseEvent.CLICK, this._loadImage);
  84.         event(this._saveButton, MouseEvent.CLICK, this._saveImage);
  85.         event(this._mikan, MouseEvent.MOUSE_DOWN, this._dragStart);
  86.     }
  87.     
  88.     
  89.     // load image
  90.     private function _loadImage(e:MouseEvent):void {
  91.         var file:FileReference = new FileReference();
  92.         event(file, Event.SELECT, this._loadFileSelected);
  93.         file.browse();
  94.     }
  95.     
  96.     private function _loadFileSelected(e:Event):void {
  97.         var file:FileReference = FileReference(e.target);
  98.         event(file, Event.COMPLETE, this._fileLoaded);
  99.         file.load();
  100.     }
  101.     
  102.     private function _fileLoaded(e:Event):void {
  103.         if (this._original) {
  104.             this._original.parent.removeChild(this._original);
  105.             this._original.unload();
  106.         }
  107.         this._original = this._base.addChildAt(new Loader(), 0as Loader;
  108.         this._original.loadBytes(FileReference(e.target).data);
  109.         event(this._original.contentLoaderInfo, Event.COMPLETE, this._imageLoaded);
  110.     }
  111.     
  112.     private function _imageLoaded(e:Event):void {
  113.         var a:Number = 256 / Math.max(this._original.width, this._original.height);
  114.         this._original.scaleX = this._original.scaleY = a;
  115.         this._original.x = this._guide.x + (256 - this._original.width) / 2;
  116.         this._original.y = this._guide.y + (256 - this._original.height) / 2;
  117.         Bitmap(this._original.content).smoothing = true;
  118.         this._event();
  119.     }
  120.     
  121.     
  122.     // manipulate mikan
  123.     private var _startScale:Number;
  124.     private var _startPoint:Point = new Point();
  125.     private function _dragStart(e:MouseEvent):void {
  126.         var sp:Sprite = Sprite(e.target);
  127.         if (e.shiftKey) {
  128.             this._startScale = sp.scaleX;
  129.             this._startPoint.x = this._base.mouseX;
  130.             this._startPoint.y = this._base.mouseY;
  131.             event(this._base.stage, MouseEvent.MOUSE_MOVE, this._scaleObject);
  132.             event(this._base.stage, MouseEvent.MOUSE_UP, this._scaleEnd);
  133.         } else {
  134.             sp.startDrag(false);
  135.             event(sp, MouseEvent.MOUSE_UP, this._dragEnd);
  136.         }
  137.     }
  138.     
  139.     private function _scaleObject(e:MouseEvent):void {
  140.         var newScale:Number = this._startScale * (this._base.mouseX - this._mikan.x) / (this._startPoint.x - this._mikan.x);
  141.         this._mikan.scaleX = this._mikan.scaleY = newScale;
  142.         event(this._base.stage, MouseEvent.MOUSE_MOVE, this._scaleObject);
  143.         event(this._base.stage, MouseEvent.MOUSE_UP, this._scaleEnd);
  144.     }
  145.     
  146.     private function _scaleEnd(e:MouseEvent):void {
  147.         this._event();
  148.     }
  149.     
  150.     private function _dragEnd(e:MouseEvent):void {
  151.         Sprite(e.target).stopDrag();
  152.         this._event();
  153.     }
  154.     
  155.     
  156.     // save image
  157.     private function _saveImage(e:Event):void {
  158.         var raw:BitmapData = new BitmapData(256256true, 0x0);
  159.         this._guide.visible = false;
  160.         raw.draw(this._base, new Matrix(1001, -this._guide.x, -this._guide.y), nullnullnulltrue);
  161.         this._guide.visible = true;
  162.         var png:ByteArray = PNGEnc.encode(raw);
  163.         raw.dispose();
  164.         var file:FileReference = new FileReference();
  165.         event(file, Event.SELECT, this._saveFileSelected);
  166.         file.save(png, 'mikaned.png');
  167.     }
  168.     
  169.     private function _saveFileSelected(e:Event):void {
  170.         this._event();
  171.     }
  172. }
  173. class MikanImage extends Sprite {
  174.     
  175.     private var _mikan:Loader;
  176.     
  177.     public function MikanImage() {
  178.         this.buttonMode = true;
  179.         this.useHandCursor = true;
  180.         this.mouseChildren = false;
  181.     }
  182.     
  183.     public function init():void {
  184.         this._mikan = this.addChild(new Loader()) as Loader;
  185.         this._mikan.contentLoaderInfo.addEventListener(Event.COMPLETE, this._mikanLoaded);
  186.         this._mikan.load(new URLRequest(MainThread.PROXY + 'http://level0.kayac.com/src/doke/mikan.png'));
  187.     }
  188.     
  189.     private function _mikanLoaded(e:Event):void {
  190.         this._mikan.x = -this._mikan.width / 2;
  191.         this._mikan.y = -this._mikan.height / 2;
  192.         this.dispatchEvent(new Event(Event.COMPLETE));
  193.     }
  194. }
  195. class Button extends SimpleButton {
  196.     
  197.     public function Button(label:String, width:int = 0):void {
  198.         var up:Sprite = _buildImage(label, 0x0, width);
  199.         var over:Sprite = _buildImage(label, 0x333333, width);
  200.         var down:Sprite = _buildImage(label, 0x333333, width);
  201.         down.y = 1;
  202.         super(up, over, down, up);
  203.     }
  204.     
  205.     private static function _buildImage(label:String, color:int, width:int = 0):Sprite {
  206.         var text:TextField = new TextField();
  207.         text.defaultTextFormat = new TextFormat('Verdana'10, 0xffffff, truenullnullnullnull, TextFormatAlign.CENTER);
  208.         text.autoSize = TextFieldAutoSize.LEFT
  209.         text.selectable = false;
  210.         text.text = label;
  211.         text.x = (width - text.width) >> 1;
  212.         text.y = 5;
  213.         var base:Shape = new Shape();
  214.         var g:Graphics = base.graphics;
  215.         g.beginFill(color);
  216.         g.drawRect(00, width, text.height + 10);
  217.         g.endFill();
  218.         var sp:Sprite = new Sprite();
  219.         sp.addChild(base);
  220.         sp.addChild(text);
  221.         return sp;
  222.     }
  223. }
  224. class Guide extends Shape {
  225.     
  226.     public function Guide() {
  227.         var g:Graphics = this.graphics;
  228.         g.lineStyle(1, 0x0, 0.3true);
  229.         g.drawRect(00255255);
  230.     }
  231. }
  232. // http://www.5etdemi.com/blog/archives/2006/12/as3-png-encoder-faster-better/
  233. class PNGEnc {
  234.     
  235.     public static function encode(img:BitmapData, type:uint = 0):ByteArray {
  236.         
  237.         // Create output byte array
  238.         var png:ByteArray = new ByteArray();
  239.         // Write PNG signature
  240.         png.writeUnsignedInt(0x89504e47);
  241.         png.writeUnsignedInt(0x0D0A1A0A);
  242.         // Build IHDR chunk
  243.         var IHDR:ByteArray = new ByteArray();
  244.         IHDR.writeInt(img.width);
  245.         IHDR.writeInt(img.height);
  246.         if(img.transparent || type == 0)
  247.         {
  248.             IHDR.writeUnsignedInt(0x08060000); // 32bit RGBA
  249.         }
  250.         else
  251.         {
  252.             IHDR.writeUnsignedInt(0x08020000); //24bit RGB
  253.         }
  254.         IHDR.writeByte(0);
  255.         writeChunk(png,0x49484452,IHDR);
  256.         // Build IDAT chunk
  257.         var IDAT:ByteArray= new ByteArray();
  258.         
  259.         switch(type)
  260.         {
  261.             case 0:
  262.                 writeRaw(img, IDAT);
  263.                 break;
  264.             case 1:
  265.                 writeSub(img, IDAT);
  266.                 break;
  267.         }
  268.         
  269.         IDAT.compress();
  270.         writeChunk(png,0x49444154,IDAT);
  271.         // Build IEND chunk
  272.         writeChunk(png,0x49454E44,null);
  273.         // return PNG
  274.         
  275.         
  276.         
  277.         return png;
  278.     }
  279.     
  280.     private static function writeRaw(img:BitmapData, IDAT:ByteArray):void
  281.     {
  282.         var h:int = img.height;
  283.         var w:int = img.width;
  284.         var transparent:Boolean = img.transparent;
  285.         
  286.         for(var i:int=0;i < h;i++) {
  287.             // no filter
  288.             if ( !transparent ) {
  289.                 var subImage:ByteArray = img.getPixels(
  290.                     new Rectangle(0, i, w, 1));
  291.                 //Here we overwrite the alpha value of the first pixel
  292.                 //to be the filter 0 flag
  293.                 subImage[0] = 0;
  294.                 IDAT.writeBytes(subImage);
  295.                 //And we add a byte at the end to wrap the alpha values
  296.                 IDAT.writeByte(0xff);
  297.             } else {
  298.                 IDAT.writeByte(0);
  299.                 var p:uint;
  300.                 for(var j:int=0;j < w;j++) {
  301.                     p = img.getPixel32(j,i);
  302.                     IDAT.writeUnsignedInt(
  303.                         uint(((p&0xFFFFFF) << 8)|
  304.                         (p>>>24)));
  305.                 }
  306.             }
  307.         }
  308.     }
  309.     
  310.     private static function writeSub(img:BitmapData, IDAT:ByteArray):void
  311.     {
  312.         var r1:uint;
  313.         var g1:uint;
  314.         var b1:uint;
  315.         var a1:uint;
  316.         
  317.         var r2:uint;
  318.         var g2:uint;
  319.         var b2:uint;
  320.         var a2:uint;
  321.         
  322.         var r3:uint;
  323.         var g3:uint;
  324.         var b3:uint;
  325.         var a3:uint;
  326.         
  327.         var p:uint;
  328.         var h:int = img.height;
  329.         var w:int = img.width;
  330.         
  331.         for(var i:int=0;i < h;i++) {
  332.             // no filter
  333.             IDAT.writeByte(1);
  334.             if ( !img.transparent ) {
  335.                 r1 = 0;
  336.                 g1 = 0;
  337.                 b1 = 0;
  338.                 a1 = 0xff;
  339.                 for(var j:int=0;j < w;j++) {
  340.                     p = img.getPixel(j,i);
  341.                     
  342.                     r2 = p >> 16 & 0xff;
  343.                     g2 = p >> 8  & 0xff;
  344.                     b2 = p & 0xff;
  345.                     
  346.                     r3 = (r2 - r1 + 256) & 0xff;
  347.                     g3 = (g2 - g1 + 256) & 0xff;
  348.                     b3 = (b2 - b1 + 256) & 0xff;
  349.                     
  350.                     IDAT.writeByte(r3);
  351.                     IDAT.writeByte(g3);
  352.                     IDAT.writeByte(b3);
  353.                     
  354.                     r1 = r2;
  355.                     g1 = g2;
  356.                     b1 = b2;
  357.                     a1 = 0;
  358.                 }
  359.             } else {
  360.                 r1 = 0;
  361.                 g1 = 0;
  362.                 b1 = 0;
  363.                 a1 = 0;
  364.                 for(j=0;j < w;j++) {
  365.                     p = img.getPixel32(j,i);
  366.                     
  367.                     a2 = p >> 24 & 0xff;
  368.                     r2 = p >> 16 & 0xff;
  369.                     g2 = p >> 8  & 0xff;
  370.                     b2 = p & 0xff;
  371.                     
  372.                     r3 = (r2 - r1 + 256) & 0xff;
  373.                     g3 = (g2 - g1 + 256) & 0xff;
  374.                     b3 = (b2 - b1 + 256) & 0xff;
  375.                     a3 = (a2 - a1 + 256) & 0xff;
  376.                     
  377.                     IDAT.writeByte(r3);
  378.                     IDAT.writeByte(g3);
  379.                     IDAT.writeByte(b3);
  380.                     IDAT.writeByte(a3);
  381.                     
  382.                     r1 = r2;
  383.                     g1 = g2;
  384.                     b1 = b2;
  385.                     a1 = a2;
  386.                 }
  387.             }
  388.         }
  389.     }
  390.     private static var crcTable:Array;
  391.     private static var crcTableComputed:Boolean = false;
  392.     private static function writeChunk(png:ByteArray, 
  393.             type:uint, data:ByteArray):void {
  394.         var c:uint;
  395.         if (!crcTableComputed) {
  396.             crcTableComputed = true;
  397.             crcTable = [];
  398.             for (var n:uint = 0; n < 256; n++) {
  399.                 c = n;
  400.                 for (var k:uint = 0; k < 8; k++) {
  401.                     if (c & 1) {
  402.                         c = uint(uint(0xedb88320) ^ 
  403.                             uint(c >>> 1));
  404.                     } else {
  405.                         c = uint(c >>> 1);
  406.                     }
  407.                 }
  408.                 crcTable[n] = c;
  409.             }
  410.         }
  411.         var len:uint = 0;
  412.         if (data != null) {
  413.             len = data.length;
  414.         }
  415.         png.writeUnsignedInt(len);
  416.         var p:uint = png.position;
  417.         png.writeUnsignedInt(type);
  418.         if ( data != null ) {
  419.             png.writeBytes(data);
  420.         }
  421.         var e:uint = png.position;
  422.         png.position = p;
  423.         c = 0xffffffff;
  424.         for (var i:int = 0; i < (e-p); i++) {
  425.             c = uint(crcTable[
  426.                 (c ^ png.readUnsignedByte()) & 
  427.                 0xff] ^ (c >>> 8));
  428.         }
  429.         c = uint(c^uint(0xffffffff));
  430.         png.position = e;
  431.         png.writeUnsignedInt(c);
  432.     }
  433. }
noswf
  1. // forked from Saqoosha's Mikan
  2. // 1. LOAD で適當な畫像をロード。
  3. // 2. みかんをドラッグで移動とか。Shift 押しながらで拡大縮小。
  4. // 3. SAVE で保存。
  5. package {
  6.     
  7.     import flash.display.Sprite;
  8.     
  9.     import org.libspark.thread.EnterFrameThreadExecutor;
  10.     import org.libspark.thread.Thread;
  11.     [SWF(width=465, height=465, backgroundColor=0xffffff, frameRate=60)]
  12.     public class Mikan extends Sprite {
  13.         
  14.         public function Mikan() {
  15.             Thread.initialize(new EnterFrameThreadExecutor());
  16.             new MainThread(this).start();
  17.         }
  18.     }
  19. }
  20. import flash.display.Bitmap;
  21. import flash.display.BitmapData;
  22. import flash.display.DisplayObject;
  23. import flash.display.Graphics;
  24. import flash.display.InteractiveObject;
  25. import flash.display.Loader;
  26. import flash.display.Shape;
  27. import flash.display.SimpleButton;
  28. import flash.display.Sprite;
  29. import flash.events.Event;
  30. import flash.events.MouseEvent;
  31. import flash.geom.Matrix;
  32. import flash.geom.Point;
  33. import flash.geom.Rectangle;
  34. import flash.net.FileReference;
  35. import flash.net.FileReferenceList;
  36. import flash.net.URLRequest;
  37. import flash.system.Security;
  38. import flash.text.TextField;
  39. import flash.text.TextFieldAutoSize;
  40. import flash.text.TextFormat;
  41. import flash.text.TextFormatAlign;
  42. import flash.utils.ByteArray;
  43. import org.libspark.thread.Thread;
  44. class MainThread extends Thread {
  45.     
  46.     public static const PROXY:String = "http://5ivestar.org/proxy/";
  47.     public static const CROSSDOMAIN:String = "http://5ivestar.org/proxy/crossdomain.xml";
  48.         
  49.     private var _base:Sprite;
  50.     private var _loadButton:Button;
  51.     private var _saveButton:Button;
  52.     private var _mikan:MikanImage;
  53.     private var _original:Loader;
  54.     private var _guide:Guide;
  55.     
  56.     public function MainThread(base:Sprite) {
  57.         this._base = base;
  58.         this._loadButton = this._base.addChild(new Button('LOAD'60)) as Button;
  59.         this._loadButton.x = this._loadButton.y = 1;
  60.         this._saveButton = this._base.addChild(new Button('SAVE'60)) as Button;
  61.         this._saveButton.x = 1;
  62.         this._saveButton.y = this._loadButton.height + 2;
  63.         this._guide = this._base.addChild(new Guide()) as Guide;
  64.         this._guide.x = this._guide.y = (465 - 256) >> 1;
  65.         Security.loadPolicyFile(CROSSDOMAIN);
  66.     }
  67.     
  68.     protected override function run():void {
  69.         this._mikan = this._base.addChildAt(new MikanImage(), 0as MikanImage;
  70.         event(this._mikan, Event.COMPLETE, this._mikanLoaded);
  71.         this._mikan.init();
  72.     }
  73.     
  74.     private function _mikanLoaded(e:Event):void {
  75.         this._mikan.scaleX = this._mikan.scaleY = 256 * 0.4 / this._mikan.width;
  76.         this._mikan.x = this._guide.x + 128;
  77.         this._mikan.y = this._guide.y + this._mikan.height / 2 + 10;
  78.         
  79.         this._event();
  80.     }
  81.     
  82.     private function _event():void {
  83.         event(this._loadButton, MouseEvent.CLICK, this._loadImage);
  84.         event(this._saveButton, MouseEvent.CLICK, this._saveImage);
  85.         event(this._mikan, MouseEvent.MOUSE_DOWN, this._dragStart);
  86.     }
  87.     
  88.     
  89.     // load image
  90.     private function _loadImage(e:MouseEvent):void {
  91.         var file:FileReference = new FileReference();
  92.         event(file, Event.SELECT, this._loadFileSelected);
  93.         file.browse();
  94.     }
  95.     
  96.     private function _loadFileSelected(e:Event):void {
  97.         var file:FileReference = FileReference(e.target);
  98.         event(file, Event.COMPLETE, this._fileLoaded);
  99.         file.load();
  100.     }
  101.     
  102.     private function _fileLoaded(e:Event):void {
  103.         if (this._original) {
  104.             this._original.parent.removeChild(this._original);
  105.             this._original.unload();
  106.         }
  107.         this._original = this._base.addChildAt(new Loader(), 0as Loader;
  108.         this._original.loadBytes(FileReference(e.target).data);
  109.         event(this._original.contentLoaderInfo, Event.COMPLETE, this._imageLoaded);
  110.     }
  111.     
  112.     private function _imageLoaded(e:Event):void {
  113.         var a:Number = 256 / Math.max(this._original.width, this._original.height);
  114.         this._original.scaleX = this._original.scaleY = a;
  115.         this._original.x = this._guide.x + (256 - this._original.width) / 2;
  116.         this._original.y = this._guide.y + (256 - this._original.height) / 2;
  117.         Bitmap(this._original.content).smoothing = true;
  118.         this._event();
  119.     }
  120.     
  121.     
  122.     // manipulate mikan
  123.     private var _startScale:Number;
  124.     private var _startPoint:Point = new Point();
  125.     private function _dragStart(e:MouseEvent):void {
  126.         var sp:Sprite = Sprite(e.target);
  127.         if (e.shiftKey) {
  128.             this._startScale = sp.scaleX;
  129.             this._startPoint.x = this._base.mouseX;
  130.             this._startPoint.y = this._base.mouseY;
  131.             event(this._base.stage, MouseEvent.MOUSE_MOVE, this._scaleObject);
  132.             event(this._base.stage, MouseEvent.MOUSE_UP, this._scaleEnd);
  133.         } else {
  134.             sp.startDrag(false);
  135.             event(sp, MouseEvent.MOUSE_UP, this._dragEnd);
  136.         }
  137.     }
  138.     
  139.     private function _scaleObject(e:MouseEvent):void {
  140.         var newScale:Number = this._startScale * (this._base.mouseX - this._mikan.x) / (this._startPoint.x - this._mikan.x);
  141.         this._mikan.scaleX = this._mikan.scaleY = newScale;
  142.         event(this._base.stage, MouseEvent.MOUSE_MOVE, this._scaleObject);
  143.         event(this._base.stage, MouseEvent.MOUSE_UP, this._scaleEnd);
  144.     }
  145.     
  146.     private function _scaleEnd(e:MouseEvent):void {
  147.         this._event();
  148.     }
  149.     
  150.     private function _dragEnd(e:MouseEvent):void {
  151.         Sprite(e.target).stopDrag();
  152.         this._event();
  153.     }
  154.     
  155.     
  156.     // save image
  157.     private function _saveImage(e:Event):void {
  158.         var raw:BitmapData = new BitmapData(256256true, 0x0);
  159.         this._guide.visible = false;
  160.         raw.draw(this._base, new Matrix(1001, -this._guide.x, -this._guide.y), nullnullnulltrue);
  161.         this._guide.visible = true;
  162.         var png:ByteArray = PNGEnc.encode(raw);
  163.         raw.dispose();
  164.         var file:FileReference = new FileReference();
  165.         event(file, Event.SELECT, this._saveFileSelected);
  166.         file.save(png, 'mikaned.png');
  167.     }
  168.     
  169.     private function _saveFileSelected(e:Event):void {
  170.         this._event();
  171.     }
  172. }
  173. class MikanImage extends Sprite {
  174.     
  175.     private var _mikan:Loader;
  176.     
  177.     public function MikanImage() {
  178.         this.buttonMode = true;
  179.         this.useHandCursor = true;
  180.         this.mouseChildren = false;
  181.     }
  182.     
  183.     public function init():void {
  184.         this._mikan = this.addChild(new Loader()) as Loader;
  185.         this._mikan.contentLoaderInfo.addEventListener(Event.COMPLETE, this._mikanLoaded);
  186.         this._mikan.load(new URLRequest(MainThread.PROXY + 'http://level0.kayac.com/src/doke/mikan.png'));
  187.     }
  188.     
  189.     private function _mikanLoaded(e:Event):void {
  190.         this._mikan.x = -this._mikan.width / 2;
  191.         this._mikan.y = -this._mikan.height / 2;
  192.         this.dispatchEvent(new Event(Event.COMPLETE));
  193.     }
  194. }
  195. class Button extends SimpleButton {
  196.     
  197.     public function Button(label:String, width:int = 0):void {
  198.         var up:Sprite = _buildImage(label, 0x0, width);
  199.         var over:Sprite = _buildImage(label, 0x333333, width);
  200.         var down:Sprite = _buildImage(label, 0x333333, width);
  201.         down.y = 1;
  202.         super(up, over, down, up);
  203.     }
  204.     
  205.     private static function _buildImage(label:String, color:int, width:int = 0):Sprite {
  206.         var text:TextField = new TextField();
  207.         text.defaultTextFormat = new TextFormat('Verdana'10, 0xffffff, truenullnullnullnull, TextFormatAlign.CENTER);
  208.         text.autoSize = TextFieldAutoSize.LEFT
  209.         text.selectable = false;
  210.         text.text = label;
  211.         text.x = (width - text.width) >> 1;
  212.         text.y = 5;
  213.         var base:Shape = new Shape();
  214.         var g:Graphics = base.graphics;
  215.         g.beginFill(color);
  216.         g.drawRect(00, width, text.height + 10);
  217.         g.endFill();
  218.         var sp:Sprite = new Sprite();
  219.         sp.addChild(base);
  220.         sp.addChild(text);
  221.         return sp;
  222.     }
  223. }
  224. class Guide extends Shape {
  225.     
  226.     public function Guide() {
  227.         var g:Graphics = this.graphics;
  228.         g.lineStyle(1, 0x0, 0.3true);
  229.         g.drawRect(00255255);
  230.     }
  231. }
  232. // http://www.5etdemi.com/blog/archives/2006/12/as3-png-encoder-faster-better/
  233. class PNGEnc {
  234.     
  235.     public static function encode(img:BitmapData, type:uint = 0):ByteArray {
  236.         
  237.         // Create output byte array
  238.         var png:ByteArray = new ByteArray();
  239.         // Write PNG signature
  240.         png.writeUnsignedInt(0x89504e47);
  241.         png.writeUnsignedInt(0x0D0A1A0A);
  242.         // Build IHDR chunk
  243.         var IHDR:ByteArray = new ByteArray();
  244.         IHDR.writeInt(img.width);
  245.         IHDR.writeInt(img.height);
  246.         if(img.transparent || type == 0)
  247.         {
  248.             IHDR.writeUnsignedInt(0x08060000); // 32bit RGBA
  249.         }
  250.         else
  251.         {
  252.             IHDR.writeUnsignedInt(0x08020000); //24bit RGB
  253.         }
  254.         IHDR.writeByte(0);
  255.         writeChunk(png,0x49484452,IHDR);
  256.         // Build IDAT chunk
  257.         var IDAT:ByteArray= new ByteArray();
  258.         
  259.         switch(type)
  260.         {
  261.             case 0:
  262.                 writeRaw(img, IDAT);
  263.                 break;
  264.             case 1:
  265.                 writeSub(img, IDAT);
  266.                 break;
  267.         }
  268.         
  269.         IDAT.compress();
  270.         writeChunk(png,0x49444154,IDAT);
  271.         // Build IEND chunk
  272.         writeChunk(png,0x49454E44,null);
  273.         // return PNG
  274.         
  275.         
  276.         
  277.         return png;
  278.     }
  279.     
  280.     private static function writeRaw(img:BitmapData, IDAT:ByteArray):void
  281.     {
  282.         var h:int = img.height;
  283.         var w:int = img.width;
  284.         var transparent:Boolean = img.transparent;
  285.         
  286.         for(var i:int=0;i < h;i++) {
  287.             // no filter
  288.             if ( !transparent ) {
  289.                 var subImage:ByteArray = img.getPixels(
  290.                     new Rectangle(0, i, w, 1));
  291.                 //Here we overwrite the alpha value of the first pixel
  292.                 //to be the filter 0 flag
  293.                 subImage[0] = 0;
  294.                 IDAT.writeBytes(subImage);
  295.                 //And we add a byte at the end to wrap the alpha values
  296.                 IDAT.writeByte(0xff);
  297.             } else {
  298.                 IDAT.writeByte(0);
  299.                 var p:uint;
  300.                 for(var j:int=0;j < w;j++) {
  301.                     p = img.getPixel32(j,i);
  302.                     IDAT.writeUnsignedInt(
  303.                         uint(((p&0xFFFFFF) << 8)|
  304.                         (p>>>24)));
  305.                 }
  306.             }
  307.         }
  308.     }
  309.     
  310.     private static function writeSub(img:BitmapData, IDAT:ByteArray):void
  311.     {
  312.         var r1:uint;
  313.         var g1:uint;
  314.         var b1:uint;
  315.         var a1:uint;
  316.         
  317.         var r2:uint;
  318.         var g2:uint;
  319.         var b2:uint;
  320.         var a2:uint;
  321.         
  322.         var r3:uint;
  323.         var g3:uint;
  324.         var b3:uint;
  325.         var a3:uint;
  326.         
  327.         var p:uint;
  328.         var h:int = img.height;
  329.         var w:int = img.width;
  330.         
  331.         for(var i:int=0;i < h;i++) {
  332.             // no filter
  333.             IDAT.writeByte(1);
  334.             if ( !img.transparent ) {
  335.                 r1 = 0;
  336.                 g1 = 0;
  337.                 b1 = 0;
  338.                 a1 = 0xff;
  339.                 for(var j:int=0;j < w;j++) {
  340.                     p = img.getPixel(j,i);
  341.                     
  342.                     r2 = p >> 16 & 0xff;
  343.                     g2 = p >> 8  & 0xff;
  344.                     b2 = p & 0xff;
  345.                     
  346.                     r3 = (r2 - r1 + 256) & 0xff;
  347.                     g3 = (g2 - g1 + 256) & 0xff;
  348.                     b3 = (b2 - b1 + 256) & 0xff;
  349.                     
  350.                     IDAT.writeByte(r3);
  351.                     IDAT.writeByte(g3);
  352.                     IDAT.writeByte(b3);
  353.                     
  354.                     r1 = r2;
  355.                     g1 = g2;
  356.                     b1 = b2;
  357.                     a1 = 0;
  358.                 }
  359.             } else {
  360.                 r1 = 0;
  361.                 g1 = 0;
  362.                 b1 = 0;
  363.                 a1 = 0;
  364.                 for(j=0;j < w;j++) {
  365.                     p = img.getPixel32(j,i);
  366.                     
  367.                     a2 = p >> 24 & 0xff;
  368.                     r2 = p >> 16 & 0xff;
  369.                     g2 = p >> 8  & 0xff;
  370.                     b2 = p & 0xff;
  371.                     
  372.                     r3 = (r2 - r1 + 256) & 0xff;
  373.                     g3 = (g2 - g1 + 256) & 0xff;
  374.                     b3 = (b2 - b1 + 256) & 0xff;
  375.                     a3 = (a2 - a1 + 256) & 0xff;
  376.                     
  377.                     IDAT.writeByte(r3);
  378.                     IDAT.writeByte(g3);
  379.                     IDAT.writeByte(b3);
  380.                     IDAT.writeByte(a3);
  381.                     
  382.                     r1 = r2;
  383.                     g1 = g2;
  384.                     b1 = b2;
  385.                     a1 = a2;
  386.                 }
  387.             }
  388.         }
  389.     }
  390.     private static var crcTable:Array;
  391.     private static var crcTableComputed:Boolean = false;
  392.     private static function writeChunk(png:ByteArray, 
  393.             type:uint, data:ByteArray):void {
  394.         var c:uint;
  395.         if (!crcTableComputed) {
  396.             crcTableComputed = true;
  397.             crcTable = [];
  398.             for (var n:uint = 0; n < 256; n++) {
  399.                 c = n;
  400.                 for (var k:uint = 0; k < 8; k++) {
  401.                     if (c & 1) {
  402.                         c = uint(uint(0xedb88320) ^ 
  403.                             uint(c >>> 1));
  404.                     } else {
  405.                         c = uint(c >>> 1);
  406.                     }
  407.                 }
  408.                 crcTable[n] = c;
  409.             }
  410.         }
  411.         var len:uint = 0;
  412.         if (data != null) {
  413.             len = data.length;
  414.         }
  415.         png.writeUnsignedInt(len);
  416.         var p:uint = png.position;
  417.         png.writeUnsignedInt(type);
  418.         if ( data != null ) {
  419.             png.writeBytes(data);
  420.         }
  421.         var e:uint = png.position;
  422.         png.position = p;
  423.         c = 0xffffffff;
  424.         for (var i:int = 0; i < (e-p); i++) {
  425.             c = uint(crcTable[
  426.                 (c ^ png.readUnsignedByte()) & 
  427.                 0xff] ^ (c >>> 8));
  428.         }
  429.         c = uint(c^uint(0xffffffff));
  430.         png.position = e;
  431.         png.writeUnsignedInt(c);
  432.     }
  433. }
noswf
Get Adobe Flash Player