BitmapDataを単純にByteArrayに入れてからsetPixelsは早い?

by yasurageruheya
BitmapData.drawの方がまだ早いみたいだ
♥0 | Line 206 | Modified 2011-05-31 05:11:31 | MIT License
play

ActionScript3 source code

/**
 * Copyright yasurageruheya ( http://wonderfl.net/user/yasurageruheya )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/kdJY
 */

package {
	import flash.display.Bitmap;
	import flash.display.BitmapData;
	import flash.display.Graphics;
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.events.MouseEvent;
	import flash.text.TextField;
	import flash.utils.ByteArray;
	import flash.system.System;
	import flash.geom.Point;
	import flash.utils.getTimer;
	public class FlashTest extends Sprite {
		private var bmp_vec:Vector.<BitmapData>;
		private var byte_vec:Vector.<BitmapDataBytes>;
		
		private var txt1:TextField;
		private var txt2:TextField;
		private var time_txt:TextField;
		
		private const COUNT:int = 1000;
		
		private var drawMethod:int;
		
		private var testTargetBMP:BitmapData;
		
		public function FlashTest() {
			// write as3 code here..
			addEventListener(Event.ENTER_FRAME, onEnterFrame);
			
			txt1 = new TextField();
			txt2 = new TextField();
			txt1.autoSize = txt2.autoSize = "left";
			txt1.y = 20;
			txt2.y = 50;
			addChild(txt1);
			addChild(txt2);
			
			var test_txt1:TextField = new TextField();
			var test_txt2:TextField = new TextField();
			var test_txt3:TextField = new TextField();
			test_txt1.autoSize = test_txt2.autoSize = test_txt3.autoSize = "left";
			test_txt1.textColor = test_txt2.textColor = test_txt3.textColor = 0xFFFFFF;
			test_txt1.selectable = test_txt2.selectable = test_txt3.selectable = false;
			
			test_txt1.text = "BitmapDataで保持しておく方式テストボタン";
			test_txt2.text = "オリジナルクラスで保持しておく方式テストボタン";
			test_txt3.text = "copyPixels or オリジナルクラスdraw";
			
			var spr1:Sprite = new Sprite();
			var spr2:Sprite = new Sprite();
			var spr3:Sprite = new Sprite();
			
			spr1.useHandCursor = spr2.useHandCursor = spr3.useHandCursor = true;
			
			spr1.addChild(test_txt1);
			spr2.addChild(test_txt2);
			spr3.addChild(test_txt3);
			
			var g:Graphics = spr1.graphics;
			
			g.beginFill(0);
			g.drawRect(0, 0, spr1.width, spr1.height);
			g.endFill();
			
			g = spr2.graphics;
			
			g.beginFill(0);
			g.drawRect(0, 0, spr2.width, spr2.height);
			g.endFill();
			
			g = spr3.graphics;
			
			g.beginFill(0);
			g.drawRect(0, 0, spr3.width, spr3.height);
			g.endFill();
			
			spr1.y = 100;
			spr2.y = 150;
			spr3.y = 200;
			
			addChild(spr1);
			addChild(spr2);
			addChild(spr3);
			
			spr1.addEventListener(MouseEvent.CLICK, test1);
			spr2.addEventListener(MouseEvent.CLICK, test2);
			spr3.addEventListener(MouseEvent.CLICK, drawTest);
			
			testTargetBMP = new BitmapData(100, 100, true, 0x0);
			var targetBMP:Bitmap = new Bitmap(testTargetBMP);
			
			targetBMP.y = 280;
			
			addChild(targetBMP);
			
			time_txt = new TextField();
			time_txt.autoSize = "left";
			time_txt.y = 250;
			
			addChild(time_txt);
		}
		
		private function test1(e:MouseEvent):void 
		{
			drawMethod = 1;
			var i:int = COUNT;
			bmp_vec = new Vector.<BitmapData>(i);
			
			while (i--)
			{
				bmp_vec[i] = new BitmapData(100, 100, true, 0x0);
				bmp_vec[i].noise(1);
			}
			
			txt2.text = "BitmapData でイメージをたくさん保持してます";
			
			testTargetBMP.fillRect(testTargetBMP.rect, 0xFFFFFF);
		}
		
		private function test2(e:MouseEvent):void 
		{
			test1(null);
			drawMethod = 0;
			
			var i:int = bmp_vec.length;
			byte_vec = new Vector.<BitmapDataBytes>(i);
			var pt:Point = new Point();
			
			while (i--)
			{
				byte_vec[i] = new BitmapDataBytes(bmp_vec[i].getPixels(bmp_vec[i].rect), bmp_vec[i].rect, pt);
				//byte_vec[i] = new BitmapDataBytes(bmp_vec[i].getVector(bmp_vec[i].rect), bmp_vec[i].rect, pt);
				bmp_vec[i].dispose();
			}
			
			txt2.text = "オリジナルクラスでイメージをたくさん保持してます";
			
			testTargetBMP.fillRect(testTargetBMP.rect, 0xFFFFFF);
		}
		
		private function drawTest(e:MouseEvent):void 
		{
			var time:int = getTimer();
			var i:int;
			testTargetBMP.lock();
			if (drawMethod)
			{
				var pt:Point = new Point();
				i = bmp_vec.length;
				while (i--)
				{
					testTargetBMP.copyPixels(bmp_vec[i], bmp_vec[i].rect, pt, null, null, true);
				}
				time_txt.text = String(getTimer() - time) + "msec : copyPixelsにかかった時間";
			}
			else
			{
				i = byte_vec.length;
				while (i--)
				{
					byte_vec[i].draw(testTargetBMP);
				}
				time_txt.text = String(getTimer() - time) + "msec : オリジナルクラスのdrawにかかった時間";
			}
			testTargetBMP.unlock();
		}
		
		private function onEnterFrame(e:Event):void 
		{
			txt1.text = "使用メモリ: "+String(numberSeparator(String(System.totalMemory / 1024)))+" KB";
		}
		
		private function numberSeparator(str:String):Array
		{
			var i:int = str.length;
			var sep:Array = [];
			while (i > 0)
			{
				sep.unshift(str.substr( -3, 3));
				str = str.substr(0, -3);
				i -= 3;
			}
			sep.push(str);
			
			
			return sep;
		}
	}
}

import flash.geom.Point;
import flash.geom.Rectangle;
import flash.utils.ByteArray;
import flash.display.BitmapData;
import flash.errors.EOFError;

class BitmapDataBytes
{
	private var bytes:ByteArray;
	//private var vec:Vector.<uint>;
	private var size:IntSize;
	public var pt:IntPoint;
	
	/**
	 * getter でwidthとかheightとか取得させとくのがいいかもしれない
	 */
	
	public function draw(target:BitmapData):void
	{
		var bmp:BitmapData = new BitmapData(size.width, size.height, true, 0x0);
		
		var b:ByteArray = bytes;
		b.position = 0;
		//var v:Vector.<uint> = vec;
		
		bmp.setPixels(bmp.rect, b);
		//bmp.setVector(bmp.rect, v);
		
		target.copyPixels(bmp, bmp.rect, new Point(pt.x, pt.y), null, null, true);
	}
	
	public function BitmapDataBytes(bytes:ByteArray, rect:Rectangle, pt:Point)
	//public function BitmapDataBytes(vec:Vector.<uint>, rect:Rectangle, pt:Point)
	{
		this.bytes = bytes;
		//this.vec = vec;
		size = new IntSize();
		size.setRect2intSize(rect);
		this.pt = new IntPoint();
		this.pt.setPoint2intPoint(pt);
	}
}

class IntSize
{
	public var width:int;
	public var height:int;
	
	public function setRect2intSize(rect:Rectangle):void
	{
		width = rect.width;
		height = rect.height;
	}
	
	public function IntSize(width:int = 0, height:int = 0)
	{
		this.width = width;
		this.height = height;
	}
}

class IntPoint
{
	public var x:int;
	public var y:int;
	
	public function setPoint2intPoint(pt:Point):void
	{
		x = pt.x;
		y = pt.y;
	}
	
	public function IntPoint(x:int = 0, y:int = 0)
	{
		this.x = x;
		this.y = y;
	}
}