最近のトラックバック

スポンサード リンク


  • Google
    Web sketch.txt-nifty.com

リンク

« ActionScript 3.0日記 - インストール | トップページ | 『マルドゥック・スクランブル―The Second Combustion 燃焼』(冲方 丁) »

ActionScript 3.0日記 - ビットマップに描画

 ActionScript ではアルファブレンドに加算や乗算が使えると聞いたので、とりあえず試してみました。

 
 とりあえず Flash Player 9 のベンチマークも兼ねて、力技で加算合成を実装してみることに。
 processing 風に1ピクセルずつ処理していこうと思ったんですが、loadPixels/updatePixels に当たる関数が見当たりません。
 少し調べたらBitmapData でピクセル毎の get/put が出来るようなのでこれを使ってみました。
package {
    import flash.display.*;
    import flash.events.*;
    
    //図形を表示する
    public class Test1 extends Sprite {
        private var bd:BitmapData;
        private var rad:Number;

        public function Test1() {
            bd = new BitmapData(320, 240, false, 0x00000000);
            rad = 16.0;
            addChild(new Bitmap(bd));
            addEventListener(Event.ENTER_FRAME, onEnterFrame);
        }

        private function alphaMul(scr:uint, scl:int):uint {
            return ((((scr>>16) & 0xff) * scl / 128) << 16) |
                ((((scr>>8) & 0xff) * scl / 128) << 8) |
                ((scr & 0xff) * scl / 128);
        }

        private function alphaAdd(scr:uint,
                                  r:int, g:int, b:int):uint {
            var dr:int = ((scr>>16) & 0xff) + r;
            var dg:int = ((scr>>8)  & 0xff) + g;
            var db:int =  (scr      & 0xff) + b;
            if (dr > 255) dr = 255;
            if (dg > 255) dg = 255;
            if (db > 255) db = 255;
            return (dr<<16)|(dg<<8)|db;
        }

        private function hotall(cx:int, cy:int, cr:int, cg:int, cb:int):void {
            var mx:int;
            var my:int;
            var col:uint;
            for(var py:int = -rad; py <= rad; py++) {
                for(var px:int = -rad; px <= rad; px++) {
                    mx = cx + px;
                    my = cy + py;
                    if (mx < 0 || mx >= width || my < 0 || my >= height) continue;
                    var r:Number = (rad - Math.sqrt(px*px+py*py)) / rad;
                    if (r < 0.0) r = 0.0;
                    if (r > 1.0) r = 1.0;
                    col = alphaAdd(bd.getPixel(mx, my), r*cr, r*cg, r*cb);
                    bd.setPixel(mx, my, col);
                }
            }
        }
    
        public function onEnterFrame(evt:Event):void {
            var col:uint;
            for(var py:int = bd.height-1; py >= 0; py--) {
                for(var px:int = bd.width-1; px >= 0; px--) {
                    col = alphaMul(bd.getPixel(px, py), 120);
                    bd.setPixel(px, py, col);
                }
            }
            hotall(mouseX, mouseY, 192, 192, 255);
            hotall(width-mouseX, height-mouseY, 255, 192, 192);
        }
    }
}
 動作例はココ。
 そこそこ動くけど重いですね。まあでも、processing もこんなものだったかも。

 簡単な色補正なら colorTransform というのを使えばいいようなので、これを使ってみます。
 円を書く部分も Bitmap 化してみますか。
Test4.as
// mxmlc -default-size 320 240 -default-frame-rate 60 Test4.as

package {
    import flash.display.*;
    import flash.events.*;
    import flash.geom.*;
    
    //図形を表示する
    public class Test4 extends Sprite {
        private var drawScr:BitmapData;
        private var rad:Number;
        private var rect:Rectangle;
        private var trans:ColorTransform;
        private var light0:Test3_0;
        private var light1:Test3_0;
        private var px:Number;
        private var py:Number;

        public function Test4() {
            drawScr = new BitmapData(320, 240, false, 0x00000000);
            rad = 16.0;
            addChild(new Bitmap(drawScr));
            addEventListener(Event.ENTER_FRAME, onEnterFrame);
            rect = new Rectangle(0, 0, drawScr.width, drawScr.height);
            trans = new ColorTransform();
            trans.redMultiplier = 0.99;
            trans.blueMultiplier = 0.99;
            trans.greenMultiplier = 0.99;
            light0 = new Test3_0();
            light0.init(15, 0x0c0606);
            light1 = new Test3_0();
            light1.init(15, 0x004040a);
            px = 320/2;
            py = 240/2;
        }

        private function alphaMul(scr:uint, scl:int):uint {
            return ((((scr>>16) & 0xff) * scl / 128) << 16) |
                ((((scr>>8) & 0xff) * scl / 128) << 8) |
                ((scr & 0xff) * scl / 128);
        }

        private function alphaAdd(scr:uint,
                                  r:int, g:int, b:int):uint {
            var dr:int = ((scr>>16) & 0xff) + r;
            var dg:int = ((scr>>8)  & 0xff) + g;
            var db:int =  (scr      & 0xff) + b;
            if (dr > 255) dr = 255;
            if (dg > 255) dg = 255;
            if (db > 255) db = 255;
            return (dr<<16)|(dg<<8)|db;
        }

        public function onEnterFrame(evt:Event):void {
            drawScr.colorTransform(rect, trans);
            var nx:Number = mouseX;
            var ny:Number = mouseY;
            var cx:Number;
            var cy:Number;
            var n:int = 20;
            for(var i:int = 0; i < n; i++) {
                cx = (px * Number(i) + nx * Number(n-i)) / Number(n);
                cy = (py * Number(i) + ny * Number(n-i)) / Number(n);
                light0.setPos(cx, cy);
                light1.setPos(width-cx, height-cy);
                drawScr.draw(light0, light0.getMtx(), null, BlendMode.ADD);
                drawScr.draw(light1, light1.getMtx(), null, BlendMode.ADD);
            }
            px = nx;
            py = ny;
        }
    }
}
Test3_0.as
package {
    import flash.display.*;
    import flash.geom.*;
    
    //図形を表示する
    public class Test3_0 extends Bitmap {
        private var mtx:Matrix;
        private var rad:int;

        public function Test3_0() {
            mtx = new Matrix();
        }

        public function getMtx():Matrix {
            return mtx;
        }

        public function setPos(tx:Number, ty:Number):void {
            mtx.tx = tx-rad; mtx.ty = ty-rad;
        }

        public function init(r:int, color:uint):void {
            rad = r;
            bitmapData = new BitmapData(rad*2+1, rad*2+1, false, 0x000000);
            var cr:int = (color>>16) & 0xff;
            var cg:int = (color>>8)  & 0xff;
            var cb:int =  color      & 0xff;
            var mx:int;
            var my:int;
            var col:uint;
            for(var py:int = -rad; py <= rad; py++) {
                for(var px:int = -rad; px <= rad; px++) {
                    mx = rad + px;
                    my = rad + py;
                    if (mx < 0 || mx >= width || my < 0 || my >= height) continue;
                    var l:Number = (rad - Math.sqrt(px*px+py*py)) / rad;
                    if (l < 0.0) l = 0.0;
                    if (l > 1.0) l = 1.0;
                    col = (int(l*cr)<<16)|(int(l*cg)<<8)|int(l*cb);
                    bitmapData.setPixel(mx, my, col);
                }
            }
        }
    }
}
 動作例はこんな感じ。
 おー速い。調子に乗って重ね書きの回数を増やしてしまいました。

 今回ファイルが複数に分かれたので makefile を書かないといけないのかなーと思ったんですが、
mxmlc -default-size 320 240 -default-frame-rate 60 Test4.as
 だけで必要なファイルをコンバイルしてくれるみたい。fcsh は前回のビルド情報を覚えていてくれるみたいなので、makefile 要らずなのかな? もしかして。
 まあ、一回目のコマンドを打つのも面倒なんで、fcsh上から make なりバッチなりが呼び出せるといいんですが…これ使えるコマンド少なすぎませんか?

« ActionScript 3.0日記 - インストール | トップページ | 『マルドゥック・スクランブル―The Second Combustion 燃焼』(冲方 丁) »

ActionScript 3.0」カテゴリの記事

コメント

これ,物凄くキレイですね!!
永久保存させて頂きました。
音楽聴きながらいじってると
時間が経つの忘れそうです。

おー意外な好反応!
どうもありがとうございます!!

ちょい豪華版も作ったので、よかったら試してみてください。重いかもしれないけど…。
http://sketch.txt-nifty.com/blog/2007/03/actionscript_5f7b.html

この記事へのコメントは終了しました。

トラックバック


この記事へのトラックバック一覧です: ActionScript 3.0日記 - ビットマップに描画:

« ActionScript 3.0日記 - インストール | トップページ | 『マルドゥック・スクランブル―The Second Combustion 燃焼』(冲方 丁) »

ブログパーツ



2021年7月
        1 2 3
4 5 6 7 8 9 10
11 12 13 14 15 16 17
18 19 20 21 22 23 24
25 26 27 28 29 30 31
無料ブログはココログ