PNGEncoder フレーム分割処理版
Flex SDK の mx.graphics.codec.PNGEncoder クラスを改造し、負荷が高くなる箇所を分割して処理を行う PNGEncoder クラスを作成しました。
すでに分割処理を行う PNGEncoder を作成されている方はいますが、私が改造したものは 指定した数値分処理を行ったら中途でループを抜けるものとなっています。イベント発行などは行わず、処理が終了したら 取得対象となる ByteArray インスタンスを返却します。
サンプルファイル一式
http://www.dango-itimi.com/blog/swf/90/sample.zip
使い方
サンプルファイルの一部を抜粋/見やすく修正
private var main:Function; private var pngEncoder:PNGEncoder; ... public function Sample() { ... pngEncoder = new PNGEncoder( new TypeBitmapData32(bitmapData), //32bit PNG エンコード指定 bitmapData.width, bitmapData.height, 5000 //1フレーム内に実行するループ数を任意に設定 ); main = encode; addEventListener(Event.ENTER_FRAME, run); } private function run(event:Event):void{ main(); } private function encode():void{ var pngBytes:ByteArray = pngEncoder.run(); trace(pngEncoder.getProgress()); if(pngBytes) main = stop; } private function stop():void {}
PngEncoder.run メソッドを実行し、戻り値が null の場合はまだ処理が完了していません。ByteArray インスタンスが返却されると処理が完了したことを示します。PngEncoder.run メソッドを実行後 PngEncoder.getProgress メソッドを呼び出すことで現在の進行状況(0~100%)が確認できます。
mx.graphics.codec.PNGEncoder では、処理行数が多くなる for 文内で if 文があり、これはなくしたほうがよいのではと考え、コンストラクタの引数には あらかじめ一定の処理を行うためのインスタンスを渡すようにしました。しかし逆にこれでは処理が遅くなってしまうという場合はごめんなさい。
サンプルでは 32bit PNG エンコードを行いますが、アルファチャンネルなしの PNG エンコードを行いたい場合は、TypeBitmapData24 クラスのインスタンスを引数に指定します。
pngEncoder = new PNGEncoder( new TypeBitmapData24(bitmapData), bitmapData.width, bitmapData.height, 5000 );
コンストラクタの第四引数に何も数値を指定しない(デフォルト数値 0を指定した)場合は、分割処理は行われません。PNGEncoder.run メソッド一度の実行で ByteArray インスタンスを取得できます。
その他改造点としまして、Array を Vector に変更しています。Flash Player 9 対応にする場合は Vector 記述箇所を Array に戻す必要があります。
mx.graphics.codec.PNGEncoder 内にある Adobe の著作権表示箇所やその他コメントは、そのまま残しておいたほうがよいのか、記述を何か変えるべきなのか、削除したほうがいいのか、どのように扱えばいいか判断がつかなかったため、改造後のソースには何も書いていません。何か問題がありましたらご指摘願います。
■ Flex SDK mx.graphics.codec.PNGEncoder
http://opensource.adobe.com/svn/opensource/flex/sdk/trunk/frameworks/projects/framework/src/mx/graphics/codec/PNGEncoder.as
[ FLASH ] [ tips ] [ update ] 投稿者 siratama : 2009年12月10日 19:07