In case Flash no longer exists; a copy of this site is included in the Flashpoint archive's "ultimate" collection.

Dead Code Preservation :: Archived AS3 works from wonderfl.net

forked from: forked from: 画像を絵画調に変換

画像を絵画調に変換
画像をクリックすると、次の画像へ。
解説など:http://game.g.hatena.ne.jp/Nao_u/20091229
副産物
/**
 * Copyright uwi ( http://wonderfl.net/user/uwi )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/qUGS
 */

// forked from uwi's forked from: 画像を絵画調に変換
// forked from Nao_u's 画像を絵画調に変換
// 
// 画像を絵画調に変換
//
// 画像をクリックすると、次の画像へ。
//
//
// 解説など:http://game.g.hatena.ne.jp/Nao_u/20091229
//

// 副産物
package {     
    import flash.display.Sprite;     
    import flash.events.*;     
    [SWF(width="465", height="465", backgroundColor="0xFFFFFF", frameRate="30")]      
        
    public class FlashTest extends Sprite {     
        public function FlashTest() {     
            Main = this;     
            startLoad();     
            stage.addEventListener(Event.ENTER_FRAME,update);      
            stage.addEventListener(MouseEvent.MOUSE_DOWN, isClick );        
         }     
    }     
}

function isClick(event:MouseEvent):void{
    Text.text = "生成中...";  
    bLoad = false;
    startLoad();     
}

import flash.display.*; 
import flash.events.*
import flash.text.TextField;     
import flash.geom.*;
import flash.utils.getTimer;
import flash.net.*; 
import flash.filters.*;

var Main:Sprite;     
var SCREEN_W:Number = 465;
var SCREEN_H:Number = 465;
var Text:TextField    
var View: Bitmap; 
var BmpData: BitmapData; 
var BmpData2: BitmapData; 
var BmpDataMono: BitmapData; 
var BmpDataEdge: BitmapData; 
var BmpDataTmp: BitmapData; 

var BITMAP_W:int = SCREEN_W;
var BITMAP_H:int = SCREEN_H;
var loaderA:Loader; 
var loaderB:Loader; 
var bLoad:Boolean = false;
var No:int = 0;
        
function startLoad():void{     
    loaderA = new Loader(); 
  
  
    var url:String;
    switch(No){
    case  0: url = "http://img.f.hatena.ne.jp/images/fotolife/N/Nao_u/20090326/20090326044849.jpg"; break;
    case  1: url = "http://img.f.hatena.ne.jp/images/fotolife/N/Nao_u/20090913/20090913133305.jpg"; break;
    case  2: url = "http://img.f.hatena.ne.jp/images/fotolife/N/Nao_u/20090817/20090817090823.jpg"; break;
    case  3: url = "http://img.f.hatena.ne.jp/images/fotolife/N/Nao_u/20090817/20080716105600.jpg"; break;
    case  4: url = "http://img.f.hatena.ne.jp/images/fotolife/N/Nao_u/20090326/20090326042031.jpg"; break;
    case  5: url = "http://img.f.hatena.ne.jp/images/fotolife/N/Nao_u/20090817/20090327043047.jpg"; break;
    case  6: url = "http://img.f.hatena.ne.jp/images/fotolife/N/Nao_u/20090326/20080810100737.jpg"; break;
    case  7: url = "http://img.f.hatena.ne.jp/images/fotolife/N/Nao_u/20090817/20080809101700.jpg"; break;
    case  8: url = "http://img.f.hatena.ne.jp/images/fotolife/N/Nao_u/20090326/20090327102950.jpg"; break;
    case  9: url = "http://img.f.hatena.ne.jp/images/fotolife/N/Nao_u/20090326/20090327090702.jpg"; break;
    case 10: url = "http://img.f.hatena.ne.jp/images/fotolife/N/Nao_u/20090326/20080716102900.jpg"; break;
    case 11: url = "http://img.f.hatena.ne.jp/images/fotolife/N/Nao_u/20090326/20090327091952.jpg"; break;
    case 12: url = "http://img.f.hatena.ne.jp/images/fotolife/N/Nao_u/20090913/20090913133218.jpg"; break;
    case 13: url = "http://img.f.hatena.ne.jp/images/fotolife/N/Nao_u/20090326/20090327043118.jpg"; break;
    case 14: url = "http://img.f.hatena.ne.jp/images/fotolife/N/Nao_u/20090326/20090326052814.jpg"; break;
    case 15: url = "http://img.f.hatena.ne.jp/images/fotolife/N/Nao_u/20090326/20080810090405.jpg"; break;
    case 16: url = "http://img.f.hatena.ne.jp/images/fotolife/N/Nao_u/20090326/20080106055925.jpg"; break;
    case 17: url = "http://img.f.hatena.ne.jp/images/fotolife/N/Nao_u/20090326/20080106044103.jpg"; break;
    case 18: url = "http://img.f.hatena.ne.jp/images/fotolife/N/Nao_u/20090817/20090817091054.jpg"; break;
    case 19: url = "http://img.f.hatena.ne.jp/images/fotolife/N/Nao_u/20090817/20091004065300.jpg"; break;
    case 20: url = "http://img.f.hatena.ne.jp/images/fotolife/N/Nao_u/20090817/20091004070000.jpg"; break;
    case 21: url = "http://img.f.hatena.ne.jp/images/fotolife/N/Nao_u/20090817/20090815193507.jpg"; break;
    case 22: url = "http://img.f.hatena.ne.jp/images/fotolife/N/Nao_u/20090817/20090326084145.jpg"; break;
    case 23: url = "http://img.f.hatena.ne.jp/images/fotolife/N/Nao_u/20090817/20090326072406.jpg"; break;
    case 24: url = "http://img.f.hatena.ne.jp/images/fotolife/N/Nao_u/20090817/20080810113647.jpg"; break;
    case 25: url = "http://img.f.hatena.ne.jp/images/fotolife/N/Nao_u/20090817/20080716105000.jpg"; break;
    case 26: url = "http://img.f.hatena.ne.jp/images/fotolife/N/Nao_u/20090817/20080115004653.jpg"; break;
    case 27: url = "http://img.f.hatena.ne.jp/images/fotolife/N/Nao_u/20090817/20080716101100.jpg"; break;
    case 28: url = "http://img.f.hatena.ne.jp/images/fotolife/N/Nao_u/20090817/20080716111200.jpg"; break;
    }
    No++;
    if( No == 29 ) No = 0;
    loaderA.load( new URLRequest(url) );
    loaderA.contentLoaderInfo.addEventListener( Event.COMPLETE, loadComplete ); 
}


function loadComplete(e:Event):void { 
    loaderB = new Loader(); 
    loaderB.contentLoaderInfo.addEventListener(Event.INIT, initialize); 
    loaderB.loadBytes(loaderA.contentLoaderInfo.bytes); 
}

function initialize(event:Event):void 
{ 
   var loader:Loader = loaderB;
   BmpData = new BitmapData(BITMAP_W, BITMAP_W, false); 
   BmpData.draw(loader);
   View = new Bitmap(BmpData); 
   View.scaleX = 1.0;
   View.scaleY = 1.0;
   Main.addChild(View);      

   BmpData2 = new BitmapData(loader.width, loader.height, false); 
   BmpDataMono = new BitmapData(loader.width, loader.height, false); 
   BmpDataEdge = new BitmapData(loader.width, loader.height, false); 
   BmpDataTmp  = new BitmapData(loader.width, loader.height, false); 

            
    
   Text = new TextField();     
   Text.text = "画像変換中・・・しばらくお待ちください";   
   Text.autoSize = "left";
   Main.addChild(Text);      

    Cnt=0;
    bLoad = true;
} 

var Cnt:int;
function update(e :Event):void{     
    if( bLoad == false ){
        return;
    }
    Cnt++;
    if( Cnt == 3 ){
        var time:int = getTimer(); 
        var cont:Number = 64;
        var mul:Number = 128 + cont;

        // モノクロ画像を生成
        FilterMono( BmpData, BmpDataMono );
        // モノクロ画像からエッジ抽出画像を生成
        FilterEdge( BmpDataMono, BmpDataEdge );
        // 元絵からぼかし画像を生成(5x5を2パス)
//        Filter3( BmpData, BmpData2 );
//        Filter3( BmpData2, BmpData );
        
        // ぼかした画像にエッジ抽出画像を乗算
        var matrix : Matrix = new Matrix(1,0,0,1,0,0);
        var color : ColorTransform = new ColorTransform(1,1,1,1,0,0,0,0);
        BmpData.draw(BmpDataEdge, matrix, color, BlendMode.MULTIPLY);
         
        var endTime:int = getTimer() - time;
        Text.text = "生成時間:" + endTime + "[ms]";   
    }
}  


// モノクロ画像を生成
function FilterMono( inBmp:BitmapData, outBmp:BitmapData):void{
    var cmf : ColorMatrixFilter = new ColorMatrixFilter([
        0.298912, 0.586611, 0.114477, 0, 0,
        0.298912, 0.586611, 0.114477, 0, 0,
        0.298912, 0.586611, 0.114477, 0, 0,
        0.298912, 0.586611, 0.114477, 0, 0
        ]);
    
    outBmp.lock(); 
    outBmp.applyFilter(inBmp, inBmp.rect, new Point(), cmf);
    outBmp.unlock(); 
}


// エッジ抽出画像を生成
function FilterEdge( inBmp:BitmapData, outBmp:BitmapData):void{
    var iB:BitmapData;
    var oB:BitmapData;
    var sum:Number = 0;
    var i : uint;

    var cf1 : ConvolutionFilter = new ConvolutionFilter(3, 3, [
        -1, 0, 1,
        -2, 0, 2,
        -1, 0, 1
        ], 1, 127);
    var cf2 : ConvolutionFilter = new ConvolutionFilter(3, 3, [
        -1, -2, -1,
        0, 0, 0,
        1, 2, 1
        ], 1, 127); 
    var mSquare : Array = new Array(256);
    for(i = 0;i < 256;i++){
        mSquare[i] = Math.min((i - 127) * (i - 127) / 15.9375, 255);
    }
    var m : Array = new Array(256);
    for(i = 0;i < 255;i++){
        m[i] = 0x000000;
    }
    m[255] = 0x737373;
    
    outBmp.lock();
    var tempB: BitmapData = inBmp.clone();
    outBmp.applyFilter(inBmp, inBmp.rect, new Point(), cf1);
    outBmp.paletteMap(outBmp, outBmp.rect, new Point(), mSquare, mSquare, mSquare); // 2乗
    tempB.applyFilter(inBmp, inBmp.rect, new Point(), cf2);
    tempB.paletteMap(tempB, tempB.rect, new Point(), mSquare, mSquare, mSquare); // 2乗
    
    outBmp.draw(tempB, null, null, BlendMode.ADD);
    tempB.dispose();
    outBmp.paletteMap(outBmp, outBmp.rect, new Point(), null, null, m);
    outBmp.unlock();

    var median : ConvolutionFilter = new ConvolutionFilter(3, 3, [
        1, 1, 1,
        1, 1, 1,
        1, 1, 1
        ]);
    
    BmpDataTmp.applyFilter(outBmp, outBmp.rect, new Point(), median);
        
        /*
    // メディアンフィルター(もどき)でノイズ除去
    BmpData.lock(); 
    iB = outBmp;
    oB = BmpDataTmp;
    for( var x:int=0; x<BITMAP_W; x++ ){ 
        for( var y:int=0; y<BITMAP_H; y++ ){ 
            sum = 0;
            var c0:Color = new Color( iB.getPixel(x-1, y-1) );
            var c1:Color = new Color( iB.getPixel(x,   y-1) );
            var c2:Color = new Color( iB.getPixel(x+1, y-1) );
            var c3:Color = new Color( iB.getPixel(x-1, y) );
            var c4:Color = new Color( iB.getPixel(x  , y) );
            var c5:Color = new Color( iB.getPixel(x+1, y) );
            var c6:Color = new Color( iB.getPixel(x-1, y+1) );
            var c7:Color = new Color( iB.getPixel(x,   y+1) );
            var c8:Color = new Color( iB.getPixel(x+1, y+1) );

            if( c0.r > 0.5 ) sum += 1.0;
            if( c1.r > 0.5 ) sum += 1.0;
            if( c2.r > 0.5 ) sum += 1.0;
            if( c3.r > 0.5 ) sum += 1.0;
            if( c4.r > 0.5 ) sum += 1.0;
            if( c5.r > 0.5 ) sum += 1.0;
            if( c6.r > 0.5 ) sum += 1.0;
            if( c7.r > 0.5 ) sum += 1.0;
            if( c8.r > 0.5 ) sum += 1.0;
            
            if( sum < 1 )   oB.setPixel(x, y, 0 ); 
            else            oB.setPixel(x, y, c4.getInt() ); 
        }
    }
    BmpData.unlock(); 
    */

    var b:Color = new Color(0);
    var col:Color = new Color(0);
    var s:Number = 0;
    var w:Number = 0;

    // ぼかし
    BmpData.lock(); 
    iB = BmpDataTmp;
    oB = outBmp;
    for( var x:int=0; x<BITMAP_W; x++ ){ 
        for( var y:int=0; y<BITMAP_H; y++ ){ 
            sum = 0;
            col.r = col.g = col.b = 0;
            b.set( iB.getPixel(x, y) );

            for( var lx:int=-2; lx<=1; lx++ ){ 
                for( var ly:int=-2; ly<=2; ly++ ){ 
                    var px:int = x+lx;
                    var py:int = y+ly;
                    if( px < 0 || px >= BITMAP_W || py < 0 || py >= BITMAP_H ) break;
                    var c:Color = new Color( iB.getPixel(px, py) );
                    
                    s = c.g - b.g;
                    if( s < 0 ) s = -s;   
                    w = 1;// - s*s;      
                    if( lx == -2 ) w *= 0.4;
                    if( ly == -2 || ly == 2 ) w *= 0.4;
                    col.r += c.r * w;
                    col.g += c.g * w;
                    col.b += c.b * w;
                    sum += w;
                }
            }
            var mul:Number = 1.0 / sum;
            col.r *= mul;
            col.g *= mul;
            col.b *= mul;
            oB.setPixel(x, y, col.getInt() ); 
        }
    } 
    BmpData.unlock(); 

}

// ぼかしフィルタ(バイラテラルフィルタっぽい感じ)
function Filter3( inBmp:BitmapData, outBmp:BitmapData):void{
    var b:Color = new Color(0);
    var col:Color = new Color(0);
    var c:Color = new Color( 0 );
    var sum:Number = 0;
    var s:Number = 0;
    var w:Number = 0;

    BmpData.lock(); 
    for( var x:int=0; x<BITMAP_W; x++ ){ 
        for( var y:int=0; y<BITMAP_H; y++ ){ 
            sum = 0;
            col.r = col.g = col.b = 0;
            b.set( inBmp.getPixel(x, y) );

            for( var lx:int=-5; lx<=5; lx++ ){ 
                for( var ly:int=-5; ly<=5; ly++ ){ 
                    c.set( inBmp.getPixel(x+lx, y+ly) );
                    
                    s = c.g - b.g;
                    if( s < 0 ) s = -s;   
                    w = 1 - s*s*s;      
                    col.r += c.r * w;
                    col.g += c.g * w;
                    col.b += c.b * w;
                    sum += w;
                }
            }
            var mul:Number = 1.0 / sum;
            col.r *= mul;
            col.g *= mul;
            col.b *= mul;
            outBmp.setPixel(x, y, col.getInt() ); 
        }
    } 
    BmpData.unlock(); 
}

// 色クラス
class Color{
    public var r:Number;
    public var g:Number;
    public var b:Number;

    public function Color( c:int ){
        r = ((c & 0xff0000)>>16)*0.003921568627;
        g = ((c & 0x00ff00)>>8)*0.003921568627;
        b = ((c & 0x0000ff))*0.003921568627;
    }

   public function set( c:int ):void{
        r = ((c & 0xff0000)>>16)*0.003921568627;
        g = ((c & 0x00ff00)>>8)*0.003921568627;
        b = ((c & 0x0000ff))*0.003921568627;
    }

    public function getInt():int{
        if( r > 1.0 ) r = 1.0;
        if( g > 1.0 ) g = 1.0;
        if( b > 1.0 ) b = 1.0;
        if( r < 0.0 ) r = 0.0;
        if( g < 0.0 ) g = 0.0;
        if( b < 0.0 ) b = 0.0;
        var col:int = ((r*255) << 16) + ((g*255)<<8) + (b*255);
        return col;
    }
}