AS3覚え書き5 :画像
Actionscriptで画像を扱うにはBitmapクラスやBitmapDataクラスを利用します。
BitmapDataクラス
Bitmap画像の各画素データを記憶するクラスです。
プロパティ
- width:int
- height:int
幅と高さ
メソッド
画素値の取得
- getPixel(x:int, y:int):uint
- getPixel32(x:int, y:int):uint
- getPixels(rect:Rectangle):ByteArray
画素値の書き込み
- setPixel(x:int, y:int, color:uint):void
- setPixel32(x:int, y:int, color:uint):void
- setPixels(rect:Rectangle, inputByteArray:ByteArray):void
32が付いているメソッドはα値付きの値ARGBを扱います。
〜Pixelsというメソッドではバイト配列を介して画素値を扱うことができます。
- draw(source:IBitmapDrawable, matrix:Matrix = null, colorTransform:ColorTransform = null, blendMode:String = null, clipRect:Rectangle = null, smoothing:Boolean = false):void
表示オブジェクトをこのビットマップに描画します。
- noise(randomSeed:int, low:uint = 0, high:uint = 255, channelOptions:uint = 7, grayScale:Boolean = false):void
ノイズ画像を生成します。
その他にも、copyやmergeなどのメソッドが用意されています。
Bitmapクラス
BitmapクラスはメンバとしてBitmapDataを持っている表示オブジェクトです。実際に画像を表示させるにはこのBitmapクラスを作成して表示リストに追加します。
プロパティ
- bitmapData : BitmapData
画素値を記録したBitmapDataです。
- smoothing : Boolean
拡大縮小などの際にスムージングを行うかどうかを設定します。
メソッドはコンストラクタ以外ありません。
Bitmap&BitmapDataクラスによる画像表示
画像表示例です。setpixel関数で全体の色を塗りつぶしてから、Bitmapデータを生成して表示させています。BitmapDataオブジェクトをコンストラクタの引数として渡して、表示するBitmapオブジェクトを作ることができます。
package { import flash.display.Sprite; public class BitmapTest extends Sprite { import flash.display.Bitmap; import flash.display.BitmapData; public function BitmapTest() { var bmpdata:BitmapData= new BitmapData(200,100); for (var j:int = 0; j< bmpdata.height; j++) { for (var i:int = 0;i< bmpdata.width; i++ ) { bmpdata.setPixel(i, j, 0xFFCCFF); } } var bitmap:Bitmap = new Bitmap(bmpdata); addChild( bitmap); } } }
表示オブジェクトをBitmapに変換する
BitmapDataクラスのdrawメソッドの引数にSpriteやMovieClipなどのDisplayObjectを渡すと、表示オブジェクトをビットマップに変換することができます。例えば、Spriteに円を描画して、ビットマップに変換したあと、赤成分だけ消して描画するような処理は下のようなコードになります。
import flash.display.Sprite; public class BitmapTest extends Sprite { import flash.display.Bitmap; import flash.display.BitmapData; public function BitmapTest() { //Spriteに絵を描く var dispObj:Sprite = new Sprite(); dispObj.graphics.beginFill(0xCCAACC); dispObj.graphics.drawCircle(20, 20, 20); dispObj.graphics.endFill(); //BitmapDataを生成する var bmpdata:BitmapData= new BitmapData(200,100); bmpdata.draw(dispObj);//SpriteをBitmapDataに変換する //BitmapDataの加工 for (var j:int = 0; j< bmpdata.height; j++) { for (var i:int = 0;i< bmpdata.width; i++ ) { var col: uint = bmpdata.getPixel(i, j); var red : int = (col >> 16) & 0x0000FF; var green : int = (col >> 8) & 0x0000FF; var blue : int = (col >> 0) & 0x0000FF; red = 0; bmpdata.setPixel(i, j, (red << 16) + (green << 8) + blue ); } } //表示用Bitmapの作成 var bitmap:Bitmap = new Bitmap(bmpdata); addChild( bitmap ); } }
外部の画像を読み込む
Loaderクラス
外部のSWF,JPG,PNGなどの画像を読み込む表示オブジェクトはLoaderとして提供されています。外部の画像を読み込むには、まずこのLoaderクラスで画像データを読み込み、DisplayObjectとして描画します。
URLRequestクラス
画像のURLを取得するにはURLRequestクラスを利用します。
BitmapData・Bitmapクラス
次にBitmapDataクラスのdrawメソッドでこのLoaderをビットマップに変換します。最後に作成したBitmapDataを持つBitmapクラスを作成して画面に表示させます。
LoaderInfoクラスとEvent.COMPLETE
ここで注意するべき点は、画像のロード完了まで待たなければならないということです。画像のサイズが未確定の状態でビットマップを生成することはできません。ロード完了時にCOMPLETEイベントが送出されるので、onCompleteLoadingというイベントハンドラ内でBitmapDataを生成、描画しています。COMPLETEイベントを扱うことができるのはLoaderInfoクラスです。LoaderクラスはLoaderInfoクラスをcontentLoaderInfoプロパティとして所有しています。
import flash.display.Sprite; public class BitmapTest extends Sprite { import flash.display.Bitmap; import flash.display.BitmapData; import flash.display.Loader; import flash.net.URLRequest; import flash.events.Event; private var myLoader:Loader = new Loader(); public function BitmapTest() { //画像のURLまたはパスを取得 var myUrlRequest:URLRequest = new URLRequest("test.jpg"); //画像を読み込む myLoader.load(myUrlRequest); //画像ロード完了時のイベントリスナーを追加 myLoader.contentLoaderInfo.addEventListener(Event.COMPLETE, onCompleteLoading); } private function onCompleteLoading(eventObject:Event):void { //Loaderと同じサイズのBitmapDataを作成する var bmpdata:BitmapData = new BitmapData(myLoader.width, myLoader.height); //Loader→BitmapDataに変換する bmpdata.draw(myLoader); //表示用Bitmapを生成 var bmp : Bitmap = new Bitmap( bmpdata ); addChild( bmp );//表示 } }
画素値を配列として扱う
Actionscriptではbyte配列用のクラスとしてByteArrayクラスが用意されています。
BitmapDataからByteArrayへ変換するには、BitmapDataのgetPixelsメソッドを利用します。引数には、抽出する矩形領域を指定して、画素データを配列として格納するByteArrayオブジェクトが戻り値となります。
//bmpdataはBitmapData var bytes:ByteArray = new ByteArray(); bytes = bmpdata.getPixels(bmpdata.rect);
逆にByteArrayからBitmapDataに戻すには、setPixelsに上書きする矩形領域と、書き込みたいByteArrayを引数にして呼び出します。
ByteArrayには現在指し示す位置offsetが定められており、positionメソッドでその値にアクセスできます。
getPixelsで値を書き込んだByteArrayオブジェクトはpositionが終端になっているため、一旦元に戻してからsetPixelに変換しないと範囲外へのアクセスとなってエラーになります。
bytes.position = 0; bmpdata.setPixels(bmpdata.rect, bytes);
getPixelで配列に変換するとARGBやRGB形式などで値が格納されます。例えばARGB形式の場合、(i,j)画素を扱う場合は次のようなindexにアクセスするとよいでしょう。
bytes[j * width * 4 + i * 4 + 0] = alpha; bytes[j * width * 4 + i * 4 + 1] = red; bytes[j * width * 4 + i * 4 + 2] = green; bytes[j * width * 4 + i * 4 + 3] = blue;
外部から画像を読み込んでbitmapDataに変換し、さらに配列に変換して画像処理を行うためのサンプルです。
import flash.display.Sprite; public class BitmapTest extends Sprite { import flash.display.Bitmap; import flash.display.BitmapData; import flash.display.Loader; import flash.net.URLRequest; import flash.events.Event; import flash.utils.ByteArray; private var myLoader:Loader = new Loader(); public function BitmapTest() { //画像のURLまたはパスを取得 var myUrlRequest:URLRequest = new URLRequest("test.jpg"); //画像を読み込む myLoader.load(myUrlRequest); myLoader.contentLoaderInfo.addEventListener(Event.COMPLETE, onCompleteLoading); } private function onCompleteLoading(eventObject:Event):void { //Loaderと同じサイズのBitmapDataを作成する var bmpdata:BitmapData = new BitmapData(myLoader.width, myLoader.height); //Loader→BitmapDataに変換する bmpdata.draw(myLoader); var bytes:ByteArray = new ByteArray(); var width:int = bmpdata.width; var height:int = bmpdata.height; //Bitmapdata→ByteArrayに変換する bytes = bmpdata.getPixels(bmpdata.rect); //ここから画像処理 var alpha:Number; var red:Number; var green:Number; var blue:Number; for (var j:int = 0; j< height; j++) { for (var i:int = 0; i < width; i++ ) { alpha = bytes[j * width * 4 + i * 4 + 0]; red= bytes[j * width * 4 + i * 4 + 1]; green= bytes[j * width * 4 + i * 4 + 2]; blue = bytes[j * width * 4 + i * 4 + 3]; red = 0;//赤だけ消去 bytes[j * width * 4 + i * 4 + 0] = alpha; bytes[j * width * 4 + i * 4 + 1] = red; bytes[j * width * 4 + i * 4 + 2] = green; bytes[j * width * 4 + i * 4 + 3] = blue; } } //ここまで画像処理 bytes.position = 0; //ByteArray→Bitmapdataに変換する bmpdata.setPixels(bmpdata.rect, bytes); var bmp : Bitmap = new Bitmap( bmpdata ); addChild( bmp ); } }