KITASENJU DESIGN BLOG

memo, html, javascript, unity

image splitting with quad-tree

export class BitmapData{

    private _context:CanvasRenderingContext2D;
    private _imageData:ImageData;
    private _img:HTMLImageElement;
    private _width:number;
    private _height:number;
    private _mean:number=0;
    private _canvas:HTMLCanvasElement;
    private _callback:()=>void;

    constructor(){

    }

    init(
        url:string,
        name:string,
        width:number,
        height:number,callback:()=>void
    ){

        this._callback = callback;

        this._canvas    = document.createElement("canvas");// == 
        this._canvas.id = ""+name;//"bitmap";      
        this._context   = this._canvas.getContext("2d");

        this._canvas.width = width;
        this._canvas.height = height;
        this._width = width;
        this._height = height;

        this._img = document.createElement("img") as HTMLImageElement; //new ImageElement();
        this._img.onload = ()=>{
            this._onLoad();
        }
        this._img.src = url;//"image2.gif?" + new Date().getTime();
        
        //document.body.appendChild(this._img);
        //document.body.appendChild(this._canvas)
    }

    private _onLoad(){

        this._context.drawImage(
            this._img, 
            0, 0, this._img.width, this._img.height, 
            0, 0, this._width, this._height
        );
        
        this._imageData = this._context.getImageData(0, 0, this._width, this._height);
        this._callback();

    }

    public getPixel(x:number, y:number):{r:number,g:number,b:number} {

        let index:number = (x + y*this._width) * 4;
        let r:number = this._imageData.data[ index ];
        let g:number = this._imageData.data[ index + 1 ];
        let b:number = this._imageData.data[ index + 2 ];
        let a:number = this._imageData.data[ index + 3 ];
        
        return {
            r: r,
            g: g,
            b: b
        };
        //return (a<<24) + (r << 16) + (g << 8) + b;

    }

    public getPixelR(rx:number, ry:number){
        //console.log(rx,ry);
        return this.getPixel(
            Math.floor(rx*this._width*0.999),
            Math.floor(ry*this._height*0.999)            
        )

    }

    public getHensa(
        xx:number,yy:number,ww:number,hh:number,per:number=1
    ):number{
        
        let m = this.getMean(xx,yy,ww,hh,per);
        
        //console.log(m);
        let sum = 0;
        let nn = 0;
        for(let j=yy;j<yy+hh;j++){
            for(let i=xx;i<xx+ww;i++){
                if(Math.random()<per){
                    sum += Math.abs( m-this.getPixel(xx,yy).r )
                    nn++;    
                }
            }
        }

        return sum/nn;

    }

    //平均値を取得する
    public getMean(
        xx:number,yy:number,ww:number,hh:number,per:number
    ):number{
        let m = 0;
        let num = 0;
        for(let j=yy; j<yy+hh; j++){
            for(let i=xx; i<xx+ww; i++){
                if( Math.random() < per ){
                    m += this.getPixel(i,j).r;
                    num++;
                }
            }
        }
        return m/num;
    }


}
import { BitmapData } from "./BitmapData";

export class QuadtreeMaker{


    bitmapData:BitmapData;
    width   :number = 512;
    height  :number = 512;
    rects   :{x:number,y:number,w:number,h:number}[];
    callback:()=>void;

    constructor(){
        
    }

    init(callback:()=>void){

        this.callback = callback;
        this.rects = [];
        this.bitmapData = new BitmapData();
        this.bitmapData.init(
            "./img/03a.jpg","lenna",512,512,()=>{
                //console.log("aaaa");
                this.load1();
            }
        );

    }

    load1(){

        //this.bitmapData.getMean(0,0,this.width,this.height,)
        this.split1(0,0,this.width,this.height,0);

        console.log(this.rects)
        this.callback();
    }


    split1(x:number,y:number,w:number,h:number,d:number){

        let hensa = this.bitmapData.getHensa(x,y,w,h);
        console.log(hensa)
        
        if(hensa<30 || d>=4 || (Math.random()<0.1 && d>=2) ){
            this.rects.push(
                {
                    x:x/this.width,
                    y:y/this.height,
                    w:w/this.width,
                    h:h/this.height
                }
            );
        }else{

            this.split1(x,y,w/2,h/2,d+1);
            this.split1(x+w/2,y,w/2,h/2,d+1);
            this.split1(x,y+h/2,w/2,h/2,d+1);
            this.split1(x+w/2,y+h/2,w/2,h/2,d+1);
            
        }

    }


}
"FOOTER"