画像処理の勉強 Bilinear法(線形補間)

今回から画像処理を少しずつ勉強していこうと思ってFlexで簡単なものを作ってみました。


Bilinear法(線形補間とも言う)というのを使って画像の拡大縮小を行うプログラム
ついでに画像の保存もできます。


こんな感じ
(ソースは右クリックで見れます。
うまく動作しない場合は最新のFlashPlayerを入れてください。
さらに保存ボタンを押しても何も反応しない場合は、F5とかで更新してからもう一度やってみてください。)


今まではグレースケールの画像しか扱ったことがなかったのでカラー画像でのやり方がよく分からなかったんですが、
ただ単にRGBそれぞれに分けて処理すればいいだけなんですね。


画像処理部分のコード

private function scaling(bai:Number):void{
    var m:uint = bmpData.width * bai;
    var n:uint = bmpData.height * bai;
    var r1:uint, g1:uint, b1:uint;
    var r2:uint, g2:uint, b2:uint;
    var r3:uint, g3:uint, b3:uint;
    var r4:uint, g4:uint, b4:uint;
    var sr:uint, sg:uint, sb:uint;
    var f00:uint, f01:uint, f10:uint, f11:uint;
    var sx:Number;
    var sy:Number;
    bmpData2 = new BitmapData(m, n);
    
    for(var i:uint = 0; i < m; i++){
        for(var j:uint = 0; j < n; j++){
            f00 = bmpData.getPixel(int(i/bai), int(j/bai));
            r1 = f00 >> 16;
            g1 = (f00 & 0x00FF00) >> 8;
            b1 = f00 & 0x0000FF;
            
            f01 = bmpData.getPixel(int(i/bai)+1, int(j/bai));
            r2 = f00 >> 16;
            g2 = (f00 & 0x00FF00) >> 8;
            b2 = f00 & 0x0000FF;
            
            f10 = bmpData.getPixel(int(i/bai), int(j/bai)+1);
            r3 = f00 >> 16;
            g3= (f00 & 0x00FF00) >> 8;
            b3 = f00 & 0x0000FF;
            
            f11 = bmpData.getPixel(int(i/bai)+1, int(j/bai)+1);
            r4 = f00 >> 16;
            g4 = (f00 & 0x00FF00) >> 8;
            b4 = f00 & 0x0000FF;
            
            sx = i/bai - int(i/bai);
            sy = j/bai - int(j/bai);
            
            sr = bilinear_calc(r1, r2, r3, r4, sx, sy);
            sg = bilinear_calc(g1, g2, g3, g4, sx, sy);
            sb = bilinear_calc(b1, b2, b3, b4, sx, sy);
            
            bmpData2.setPixel(i, j, (sr << 16) | (sg << 8) | sb);
        }
    }
    
    view.bitmapData = bmpData2;
    view.width = 300*bai;
    view.height = 300*bai;
}

private function bilinear_calc(f00:Number, f01:Number, f10:Number, f11:Number, sx:Number, sy:Number):Number{
    return f00*(1-sx)*(1-sy)+f01*sx*(1-sy)+f01*(1-sx)*sy+f11*sx*sy;
}


アルゴリズムこちらのサイトを見てなんとなく理解は出来た。