鉛筆画調処理

matsu45122009-08-14



エフェクト処理に鉛筆画調処理を追加
こちらからどうぞ
ソースは右クリックで


以下の処理を組み合わせることによって実現しています。
色彩強調
エッジ抽出
鮮鋭化
平滑化


色彩強調は以下の部分

 ro= ( rr*f1-gg*f2-bb*f2)/FACTOR;
 go= (-rr*f2+gg*f1-bb*f2)/FACTOR;
 bo= (-rr*f2-gg*f2+bb*f1)/FACTOR;


ro,go,boは強調処理をした後の値。f1,f2は重み。FCTORは256


ソース

private function pencil_effect(act:int, st:int, sm:int):void
{
    if(target_bmpData == null) return;
    bmpData2 = new BitmapData(target_bmpData.width, target_bmpData.height);
    
    const FACTOR:int = 256;
    var x:int, y:int;
    var xx:int, yy:int;

    var f1:int, f2:int;

    var err:int, egg:int, ebb:int;
    var sr_x:int, sg_x:int, sb_x:int;
    var sr_y:int, sg_y:int, sb_y:int;
    var r1:int, g1:int, b1:int, dum1:int, dum2:int;
    var rr:int, gg:int, bb:int, ed:int;
    var ro:int, go:int, bo:int;
    var ff:int;
    var st2:int, con:int;
    var sum:int;
    var endn:int, endn3:int, endo:int;
    var col:Color = new Color(), ncol:Color = new Color();
    //平滑化フィルター
    var smooth:Array = [];
    //鮮鋭化フィルター
    var fil:Array=[
        -1,-1,-1,
        -1, 8,-1,
        -1,-1,-1];
    var sobel1:Array=[
         1, 0,-1,
         2, 0,-2,
         1, 0,-1];
    var sobel2:Array=[
         1, 2, 1,
         0, 0, 0,
        -1,-2,-1];
    var factor:Array = [ 1.25, 1.5, 1.75, 2.0, 2.5, 3.0, 4.0 ];    /* 強調係数 */
    var x1:int, y1:int, x2:int, y2:int;

    x1 = 0;
    y1 = 0;
    x2 = bmpData2.width - 1;
    y2 = bmpData2.height - 1;

    // 平滑化フィルタの設定
    sum = 0;
    for(ff=0;ff<9;ff++) {
        if(ff==4) {
            smooth[ff]=10;
            sum+=10;
        }
        else {
            smooth[ff]=sm;
            sum+=sm;
        }
    }

    f1 = int(Number(FACTOR) * factor[act]);
    f2 = int(Number(FACTOR) * (factor[act] - 1.0)/2.0);

    // 色彩強調処理
    for(y=y1;y<=y2;y++) {
        for(x=x1;x<=x2;x++) {
            col.color = target_bmpData.getPixel(x , y);    
            rr= col.r;
            gg= col.g;
            bb= col.b;
            //原色に近づける
            ro= ( rr*f1-gg*f2-bb*f2)/FACTOR;
            go= (-rr*f2+gg*f1-bb*f2)/FACTOR;
            bo= (-rr*f2-gg*f2+bb*f1)/FACTOR;
            col.r = ro;
            col.g = go;
            col.b = bo;
            bmpData2.setPixel(x, y, col.color);
        }
    }

    st2 = st/2;
    con = 66;
    
    for(y = y1; y <= y2; y++) {
        for(x = x1; x <= x2; x++) {
            err = egg = ebb = 0;
            sr_x = sg_x = sb_x = 0;
            sr_y = sg_y = sb_y = 0;
            ff = 0;
            for(yy = -1; yy <= 1; yy++) {
                for(xx = -1; xx <= 1; xx++) {
                    // エッジを求めるのは,元画像が対象
                    col.color = target_bmpData.getPixel(x+xx, y+yy);    
                    // 先鋭化フィルタ
                    err -= col.r * fil[ff];
                    egg -= col.g * fil[ff];
                    ebb -= col.b * fil[ff];

                    // Sobelによるエッジ抽出
                    sr_x += col.r * sobel1[ff];
                    sg_x += col.g * sobel1[ff];
                    sb_x += col.b * sobel1[ff];
                    sr_y += col.r * sobel2[ff];
                    sg_y += col.g * sobel2[ff];
                    sb_y += col.b * sobel2[ff];

                    ff++;
                }
            }
            // 色彩強調した後の値を取得
            col.color = bmpData2.getPixel(x , y);    
            r1 = col.r;
            g1 = col.g;
            b1 = col.b;
            // エッジ部分を特に強調
            err = err * st / 100 + int(Math.sqrt(sr_x*sr_x+sr_y*sr_y)) * st2 / 100;
            egg = egg * st / 100 + int(Math.sqrt(sg_x*sg_x+sg_y*sg_y)) * st2 / 100;
            ebb = ebb * st / 100 + int(Math.sqrt(sb_x*sb_x+sb_y*sb_y)) * st2 / 100;
            //色を変換
            rr = getPencilVal(err, int(col.r), con);
            gg = getPencilVal(egg, int(col.g), con);
            bb = getPencilVal(ebb, int(col.b), con);
            col.r = rr;
            col.g = gg;
            col.b = bb;
            bmpData2.setPixel(x, y, col.color);    
        }
    }
    
    // 平滑化処理
    var filter:ConvolutionFilter = new ConvolutionFilter(3, 3, smooth, sum);
    bmpData2.applyFilter(bmpData2, bmpData2.rect, new Point, filter);
    
    view.bitmapData = target_bmpData = bmpData2;
    myImage.width = view.width = myImage.width;
    myImage.height = view.height = myImage.height;
}