bitmapDataのAlpha切り抜き比較
先のmqoのパースで必要になったので考えられる方法で速度比較。パースの時にはpbjでフィルターを作りました。
512*512でほぼ同速 1024*1024になると自分の環境ではfilterを使ったほうが速かったです
/**
* Copyright zahir ( http://wonderfl.net/user/zahir )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/oKyk
*/
package
{
import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.display.BitmapDataChannel;
import flash.display.Sprite;
import flash.geom.Point;
import flash.geom.Rectangle;
import flash.text.TextField;
import flash.utils.getTimer;
[SWF(width="465",height="465",backgroundColor="0x999999")]
public class wonderfl extends Sprite
{
private const ZERO:Point = new Point(0,0);
private var len:int = 100;
private var src:BitmapData;
private var alphaMap:BitmapData;
private var bd:BitmapData;
private var filter:G2AFilter;
private var rect:Rectangle;
private var t:TextField;
public function wonderfl()
{
var size:int = 465/3;
src = new GradientBitmapData( size, size ).data;
alphaMap = new AlphaMap( size, size ).data;
bd = new BitmapData( size,size, true, 0 );
filter = new G2AFilter();
rect = bd.rect;
addChild( ( t = new TextField() )).width = 465;
t.height = 465 - size;
t.y = size;
addChild( new Bitmap( src ) );
addChild( new Bitmap( alphaMap) ).x = size;
addChild( new Bitmap(bd) ).x = size * 2;
loop( "useFilter :: ", useFilter );
loop( "useCopyChannel :: ", useCopyChannel );
loop( "bad :: ", bad );
}
private function loop( txt:String, func:Function ):void
{
var time:int = getTimer();
for(var i:int = 0; i<len; i++) func();
var comp:int = getTimer() - time;
t.appendText( txt + comp + " ms\n" );
}
private function useFilter():void
{
bd.applyFilter( alphaMap, rect, ZERO, filter );
bd.copyPixels( src, rect, ZERO, bd, ZERO );
}
private function useCopyChannel():void
{
bd.copyPixels( src, rect, ZERO );
bd.copyChannel( alphaMap, rect, ZERO, BitmapDataChannel.RED, BitmapDataChannel.ALPHA);
}
public function bad():void
{
bd.copyPixels( src, rect, ZERO );
var x:int = bd.width;
var y:int = bd.height;
for(var j:int = 0; j < x; j++)
{
for(var i:int = 0; i<y; i++)
{
var c:uint = alphaMap.getPixel( i, j);
var _a:int = c &0xFF;
c = _a <<24 | bd.getPixel( i,j );
bd.setPixel32( i, j, c );
}
}
}
}
}
import flash.display.BitmapData;
import flash.display.GradientType;
import flash.display.Graphics;
import flash.display.Shader;
import flash.display.Shape;
import flash.filters.ShaderFilter;
import flash.geom.Matrix;
import flash.utils.ByteArray;
import mx.utils.Base64Decoder;
class AbstBitmapData
{
protected var bd:BitmapData;
public function AbstBitmapData( w:int, h:int )
{
bd = new BitmapData(w,h,false, 0xFFFFFF);
setup();
}
protected function setup():void
{
}
public function get data():BitmapData
{
return bd.clone();
}
}
class GradientBitmapData extends AbstBitmapData
{
public function GradientBitmapData( w:int, h:int)
{
super(w,h);
}
override protected function setup():void
{
var s:Shape = new Shape();
var g:Graphics = s.graphics;
var m:Matrix = new Matrix();
m.createGradientBox( bd.width, bd.height );
g.beginGradientFill( "linear", [0xFF0000, 0xFFFF00, 0x00FF00], [1,1,1], [0,0x88,0xFF],m);
g.drawRect( 0,0, bd.width, bd.height );
g.endFill();
bd.draw( s );
}
}
class AlphaMap extends AbstBitmapData
{
public function AlphaMap(w:int,h:int)
{
super(w,h);
}
override protected function setup():void
{
var s:Shape = new Shape();
var g:Graphics = s.graphics;
var m:Matrix = new Matrix();
m.createGradientBox( bd.width, bd.height );
g.beginGradientFill( "radial", [0, 0xFFFFFF], [1,1], [0x99,0xFF],m);
g.drawRect( 0,0, bd.width, bd.height );
g.endFill();
bd.draw( s );
}
}
/*
* srcのRedチャンネルをAlphaにするだけのPixelBenerFilter
*/
class G2AFilter extends ShaderFilter{
static private var code:ByteArray;
{ static private var dec:Base64Decoder = new Base64Decoder() ;
dec.decode(
"pQEAAACkCQBHMkFGaWx0ZXKgDG5hbWVzcGFjZQBqcC56YWhpcgCgDHZlbmRvcgB6YWhpcgCgCHZl" +
"cnNpb24AAQCgDGRlc2NyaXB0aW9uAGdyYXlTY2FsZSAtPiBhbHBoYQChAQIAAAxfT3V0Q29vcmQA" +
"owAEc3JjAKECBAEAD2RzdAAwAgDxAAAQAB0BAPMCABsAHQEAEAEAAAA=" );
code = dec.toByteArray(); dec = null;
}public function G2AFilter(){ super( new Shader( code) ) }
}