[AS3.0] BitmapDataSaverクラスに挑戦!

SWF上で描いた画像をローカルに保存するBitmapDataSaverクラスをAS3.0クラスで作ってみる。 :bouzu:

FileReferenceクラスを使うよ。 :boy:
BitmapDataクラスに新しく追加されたencode()メソッドもね! :cake:

:caution: 要 Flash Player 11.3 以上

This movie requires Flash Player 11.3.0

BitmapDataSaver.as (net.BitmapDataSaver.as)
package net {

  import flash.events.EventDispatcher;
  import flash.net.FileReference;
  import flash.utils.ByteArray;
  import flash.display.BitmapData;
  import flash.events.Event;
  import flash.events.ProgressEvent;
  import flash.events.IOErrorEvent;
  import flash.events.HTTPStatusEvent;
  import flash.events.SecurityErrorEvent;
  import flash.geom.Rectangle;

  import flash.display.PNGEncoderOptions;
  import flash.display.JPEGEncoderOptions;
  import flash.display.JPEGXREncoderOptions;


  public class BitmapDataSaver extends EventDispatcher {
    // プロパティ
    private var file:FileReference;
    private var imageType:String;
    public static const PNG:String = "png";
    public static const JPEG:String = "jpg";
    public static const JPEGXR:String = "jpgxr";

    // コンストラクタ
    public function BitmapDataSaver() {
      init();
    }

    // メソッド
    private function init():void {
      file = new FileReference();
      file.addEventListener(Event.OPEN, open, false, 0, true);
      file.addEventListener(ProgressEvent.PROGRESS, progress, false, 0, true);
      file.addEventListener(Event.COMPLETE, complete, false, 0, true);
      file.addEventListener(IOErrorEvent.IO_ERROR, ioerror, false, 0, true);
      file.addEventListener(HTTPStatusEvent.HTTP_STATUS, httpstatus, false, 0, true);
      file.addEventListener(SecurityErrorEvent.SECURITY_ERROR, securityerror, false, 0, true);

    }
    public function save(bd:BitmapData, defaultName:String, type:String, options:Object = null):void {
      var bitmapData:BitmapData = new BitmapData(bd.width, bd.height);
      bitmapData.lock();
      bitmapData.draw(bd);
      bitmapData.unlock();

      var fastCompression:Boolean = false;
      var quality:uint = 80;
      var quantization:uint = 20;
      var colorSpace:String = "auto";
      var trimFlexBits:uint = 0;
      if (options) {
        transparent = options.transparent;
        fastCompression = options.fastCompression;
        quality = options.quality;
        quantization = options.quantization;
        colorSpace = options.colorSpace;
        trimFlexBits = options.trimFlexBits;
      }
      var byteArray:ByteArray = new ByteArray();
      switch (type) {
        case PNG :
          bitmapData.encode(bitmapData.rect, new PNGEncoderOptions(fastCompression), byteArray);
          break;
        case JPEG :
          bitmapData.encode(bitmapData.rect, new JPEGEncoderOptions(quality), byteArray);
          break;
        case JPEGXR :
          bitmapData.encode(bitmapData.rect, new JPEGXREncoderOptions(quantization, colorSpace, trimFlexBits), byteArray);
          break;
      }
      file.save(byteArray, defaultName);
      bitmapData.dispose();
    }
    private function open(evt:Event):void {
      dispatchEvent(evt);
    }
    private function progress(evt:ProgressEvent):void {
      dispatchEvent(evt);
    }
    private function complete(evt:Event):void {
      dispatchEvent(evt);
    }
    private function ioerror(evt:IOErrorEvent):void {
      dispatchEvent(evt);
    }
    private function httpstatus(evt:HTTPStatusEvent):void {
      dispatchEvent(evt);
    }
    private function securityerror(evt:SecurityErrorEvent):void {
      dispatchEvent(evt);
    }

  }

}

Main.as
package {

  import flash.display.Sprite;
  import flash.display.BitmapData;
  import flash.display.Bitmap;
  import flash.events.Event;
  import flash.events.MouseEvent;
  import net.BitmapDataSaver;
  import controls.Btn;


  [SWF(backgroundColor="#FFFFFF", width="440", height="480", frameRate="30")]

  public class Main extends Sprite {
    // プロパティ
    private var saver:BitmapDataSaver;
    private var saveBtn:Btn;
    private var bitmap:Bitmap;

    // コンストラクタ
    public function Main() {
      init();
    }

    // メソッド
    private function init():void {
      saver = new BitmapDataSaver();
      saver.addEventListener(Event.COMPLETE, complete, false, 0, true);
      saveBtn = new Btn();
      addChild(saveBtn);
      saveBtn.x = 220;
      saveBtn.y = 455;
      saveBtn.init({label: "save"});
      saveBtn.addEventListener(MouseEvent.CLICK, save, false, 0, true);
      var photo:Photo = new Photo(400, 400);
      bitmap = new Bitmap(photo);
      addChild(bitmap);
      bitmap.x = 20;
      bitmap.y = 20;
    }
    private function save(evt:MouseEvent):void {
      var bitmapData:BitmapData = bitmap.bitmapData;
      saver.save(bitmapData, "piyo.ing", BitmapDataSaver.PNG);
    }
    private function complete(evt:Event):void {
    }

  }

}

encode()メソッド
public function encode(rect:Rectangle, compressor:Object, byteArray:ByteArray = null):ByteArray
選択したコンプレッサアルゴリズムを使用してこの BitmapData オブジェクトを圧縮し、新しい ByteArray オブジェクトを返します。

パラメータ
rect:Rectangle
BitmapData オブジェクトの圧縮領域です。
compressor:Object
使用するコンプレッサのタイプです。有効な値は、flash.display.PNGEncoderOptions、flash.display.JPEGEncoderOptions および flash.display.JPEGXREncoderOptions です。
byteArray:ByteArray (default = null)
エンコードされた画像を格納する出力用の ByteArray です。

戻り値
ByteArray
エンコードされた画像を含む ByteArray です。