forked from: ScalingBitmapFill 速度比較
forked from ScalingBitmapFill 速度比較 (diff: 12)
FP9版は逐一再計算してるのでFP10版も再計算するようにしてみた。 最適化をする前はFP10 APIは660ms でした。今は 200ms 3倍速くなった! 自分の結果 FP9 API :: 158ms FP10 API :: 199ms drawGraphicsData :: 123ms copyForm :: 101ms
ActionScript3 source code
/**
* Copyright zahir ( http://wonderfl.net/user/zahir )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/4epR
*/
// forked from zahir's ScalingBitmapFill 速度比較
// FP9版は逐一再計算してるのでFP10版も再計算するようにしてみた。
// 最適化をする前はFP10 APIは660ms でした。今は 200ms
// 3倍速くなった!
/*
自分の結果
FP9 API :: 158ms
FP10 API :: 199ms
drawGraphicsData :: 123ms
copyForm :: 101ms
*/
package{
import flash.display.Bitmap;
import flash.display.IGraphicsData;
import flash.display.Loader;
import flash.display.Shape;
import flash.display.Sprite;
import flash.events.Event;
import flash.events.MouseEvent;
import flash.net.URLRequest;
import flash.system.LoaderContext;
import flash.text.TextField;
import flash.utils.getTimer;
[SWF(width="465", height="465", backgroundColor="0xFFFFFF")]
public class ScalingBitmapFill_test extends Sprite{
private var t:TextField;
private var l:Loader;
private var sbf9:ScalingBitmapFill_9;
private var sbf10:ScalingBitmapFill_10;
private var v:Vector.<IGraphicsData>;
private var s:Shape;
public function ScalingBitmapFill_test(){
addChild( (t = new TextField()) );
t.width = t.height = 465;
s = new Shape();
l = new Loader();
l.contentLoaderInfo.addEventListener(Event.COMPLETE, onComp);
l.load( new URLRequest("http://zahir.coresv.com/wonderfl/img/scalingBitmapTest.png"), new LoaderContext(true) );
}
private function onComp(e:Event):void{
l.contentLoaderInfo.removeEventListener(Event.COMPLETE, onComp);
var bmp:Bitmap = l.content as Bitmap;
sbf9 = new ScalingBitmapFill_9(bmp.bitmapData , 100,100, 40, 40, 40, 40 );
sbf10 = new ScalingBitmapFill_10(bmp.bitmapData , 100,100, 40, 40, 40, 40 );
v = sbf10.getGraphicData();
excute();
stage.addEventListener(MouseEvent.CLICK, click);
}
private function click(e:MouseEvent):void{
t.text = "";
excute();
}
private function excute():void{
var len:int = 10000;
var i:int = 0;
var time:int = getTimer();
sbf10.draw( graphics );
// 9 API
time = getTimer();
for(i=0; i<len; i++){
s.graphics.clear();
sbf9.draw( s.graphics );
}
t.appendText( "FP9 API :: " + ( getTimer() - time) + "ms\n\n" );
// 10 API
time = getTimer();
for(i=0; i<len; i++){
s.graphics.clear();
sbf10.draw( s.graphics );
}
t.appendText( "FP10 API :: " + ( getTimer() - time) + "ms\n\n" );
// 10 drawGraphicsData
time = getTimer();
for(i=0; i<len; i++){
s.graphics.clear();
s.graphics.drawGraphicsData( v );
}
t.appendText( "drawGraphicsData :: " + ( getTimer() - time) + "ms\n\n" );
// 10 copyForm
time = getTimer();
for(i=0; i<len; i++){
s.graphics.clear();
s.graphics.copyFrom( graphics );
}
t.appendText( "copyForm :: " + ( getTimer() - time) + "ms\n\n" );
s.graphics.clear();
graphics.clear();
}
}
}
import flash.display.BitmapData;
import flash.display.Graphics;
import flash.display.GraphicsBitmapFill;
import flash.display.GraphicsPath;
import flash.display.IGraphicsData;
import flash.geom.Matrix;
import flash.display.GraphicsEndFill;
import flash.display.GraphicsSolidFill;
import __AS3__.vec.Vector;
class AbstScalingBitmapFill
{
protected var _bitmapData:BitmapData;
private var _smooth:Boolean;
private var _left:Number;
private var _top:Number;
private var _right:Number;
private var _bottom:Number;
private var _width:Number;
private var _height:Number;
private var _innerWidth:Number;
private var _innerHeight:Number;
protected var v:Vector.<IGraphicsData>;
protected var flg:Boolean = false;
public function AbstScalingBitmapFill(
bitmapData:BitmapData,
width:int, height:int,
left:int = 0, top:int = 0, right:int = 0, bottom:int = 0,
smooth:Boolean = false) {
v = new Vector.<IGraphicsData>;
setData( bitmapData, width, height, left, top, right, bottom, smooth);
}
public function setData(
bitmapData:BitmapData,
width:int, height:int,
left:int = 0, top:int = 0, right:int = 0, bottom:int = 0,
smooth:Boolean = false):void{
this.bitmapData = bitmapData;
this.width = width;
this.height = height;
this.left = left;
this.top = top;
this.right = right;
this.bottom = bottom;
this.smooth = smooth;
}
public function draw( graphics:Graphics ):Graphics{
return null;
}
public function set bitmapData(value:BitmapData):void {
_bitmapData = value.clone();
flg = false;
}
public function get left():Number { return _left; }
public function set left(value:Number):void
{
if (value == _left) return;
value = (value < 0) ? 0 : value;
_left = value;
flg = false;
}
public function get top():Number { return _top; }
public function set top(value:Number):void
{
if (value == _top) return;
value = (value < 0) ? 0 : value;
_top = value;
flg = false;
}
public function get right():Number { return _right; }
public function set right(value:Number):void
{
if (value == _right) return;
value = (value < 0) ? 0 : value;
_right = value;
flg = false;
}
public function get bottom():Number { return _bottom; }
public function set bottom(value:Number):void
{
if (value == _bottom) return;
value = (value < 0) ? 0 : value;
_bottom = value;
flg = false;
}
public function get width():Number { return _width; }
public function set width(value:Number):void
{
if (value == _width) return;
value = (value < 0) ? 0 : value;
_width = value;
flg = false;
}
public function get height():Number { return _height; }
public function set height(value:Number):void
{
if (value == _height) return;
value = (value < 0) ? 0 : value;
_height = value;
flg = false;
}
public function get smooth():Boolean { return _smooth; }
public function set smooth(value:Boolean):void
{
if (value == _smooth) return;
_smooth = value;
flg = false;
}
public function get innerWidth():Number { return width - (left + top); }
public function get innerHeight():Number { return height - (top + bottom); }
protected function box( dx:int = 0, dy:int = 0, scaleX:Number = 1, scaleY:Number = 1):Matrix{
var m:Matrix = new Matrix();
m.scale( scaleX, scaleY );
m.translate( dx, dy );
return m;
}
}
class ScalingBitmapFill_9 extends AbstScalingBitmapFill{
private var g:Graphics;
public function ScalingBitmapFill_9(
bitmapData:BitmapData,
width:int, height:int,
left:int = 0, top:int = 0, right:int = 0, bottom:int = 0,
smooth:Boolean = false) {
super(bitmapData, width, height, left, top, right, bottom, smooth);
}
override public function draw(graphics:Graphics):Graphics{
g = graphics;
var minWidth:Number = left + right;
var minHeight:Number = top + bottom;
var innerWidth:Number = this.innerWidth, innerHeight:Number = this.innerHeight;
if (minWidth >= width) width = minWidth, innerWidth = 0;
if (minHeight >= height) height = minHeight, innerHeight = 0;
var r:int = width - right;
var b:int = height - bottom;
var sx:Number = innerWidth / (_bitmapData.width - minWidth);
var sy:Number = innerHeight / (_bitmapData.height - minHeight);
var offsetX1:Number = left - left * sx;
var offsetX2:Number = width % _bitmapData.width;
var offsetY1:Number = top - top * sy;
var offsetY2:Number = height % _bitmapData.height;
// top
drawRect(0,0, left,top );
drawRect(left,0, innerWidth,top, box(offsetX1,0,sx) );
drawRect(r,0, right,top, box(offsetX2) );
// middle
drawRect(0,top, left, innerHeight, box(0,offsetY1, 1,sy) );
drawRect(left,top, innerWidth, innerHeight, box( offsetX1, offsetY1, sx,sy ) );
drawRect(r,top, right, innerHeight, box( offsetX2,offsetY1, 1,sy ) );
// bottom
drawRect(0, b, left,top , box( 0, offsetY2 ));
drawRect(left,b, innerWidth,top, box( offsetX1, offsetY2, sx ) );
drawRect(r,b, right,top, box( offsetX2, offsetY2 ) );
return graphics;
}
private function drawRect(x:Number, y:Number, width:Number, height:Number, matrix:Matrix = null):void{
g.beginBitmapFill( _bitmapData, matrix, true, smooth );
g.drawRect( x, y, width,height );
g.endFill();
}
}
class ScalingBitmapFill_10 extends AbstScalingBitmapFill{
private var command:Vector.<int> = Vector.<int>([1, 2, 2, 2, 2]);
private var paths:Vector.<GraphicsPath>;
private var fills:Vector.<GraphicsBitmapFill>;
public function ScalingBitmapFill_10(
bitmapData:BitmapData,
width:int, height:int,
left:int = 0, top:int = 0, right:int = 0, bottom:int = 0,
smooth:Boolean = false) {
paths = new Vector.<GraphicsPath>();
fills = new Vector.<GraphicsBitmapFill>();
for(var i:int = 0; i<9; i++){
paths[i] = new GraphicsPath(command, new Vector.<Number>(10));
fills[i] = new GraphicsBitmapFill(bitmapData, null, true, smooth);
}
super(bitmapData, width, height, left, top, right, bottom, smooth);
}
public function getGraphicData():Vector.<IGraphicsData>{
return v;
}
override public function draw(graphics:Graphics):Graphics
{
//if (flg == false)
calc();
graphics.drawGraphicsData( v );
return graphics;
}
private function calc():void
{
var minWidth:Number = left + right;
var minHeight:Number = top + bottom;
var innerWidth:Number = this.innerWidth, innerHeight:Number = this.innerHeight;
if (minWidth >= width) width = minWidth, innerWidth = 0;
if (minHeight >= height) height = minHeight, innerHeight = 0;
var r:int = width - right;
var b:int = height - bottom;
var sx:Number = innerWidth / (_bitmapData.width - minWidth);
var sy:Number = innerHeight / (_bitmapData.height - minHeight);
var offsetX1:Number = left - left * sx;
var offsetX2:Number = width % _bitmapData.width;
var offsetY1:Number = top - top * sy;
var offsetY2:Number = height % _bitmapData.height;
v.length = 0;
// LT
v.push( setFill( fills[0] ), drawRect(paths[0], 0, 0, left, top));
// T
v.push( setFill( fills[1], box( offsetX1,0,sx)), drawRect(paths[1], left,0, innerWidth,top));
// RT
v.push( setFill( fills[2], box(offsetX2)), drawRect(paths[2], r,0, right,top));
// L
v.push( setFill( fills[3], box( 0,offsetY1, 1,sy )), drawRect(paths[3], 0,top, left, innerHeight));
// Center
v.push( setFill( fills[4], box( offsetX1, offsetY1, sx,sy )), drawRect(paths[4], left,top, innerWidth, innerHeight));
// right
v.push( setFill( fills[5], box( offsetX2,offsetY1, 1,sy )), drawRect(paths[5], r,top, right, innerHeight));
// LB
v.push( setFill( fills[6], box( 0, offsetY2 )), drawRect(paths[6], 0, b, left,top) );
// B
v.push( setFill( fills[7], box( offsetX1, offsetY2, sx )), drawRect(paths[7], left,b, innerWidth,top) );
// RB
v.push( setFill( fills[8], box( offsetX2, offsetY2 )), drawRect(paths[8], r,b, right,top) );
flg = true;
}
private function drawRect( path:GraphicsPath, x:Number, y:Number, width:Number, height:Number):GraphicsPath {
path.data[0] = path.data[6] = path.data[8] = x;
path.data[1] = path.data[3] = path.data[9] = y;
path.data[2] = path.data[4] = x + width;
path.data[5] = path.data[7] = y + height;
return path;
}
private function setFill( fill:GraphicsBitmapFill, matrix:Matrix = null):GraphicsBitmapFill{
fill.bitmapData = _bitmapData;
fill.matrix = matrix;
fill.smooth = smooth;
return fill;
}
}