2017年2月9日木曜日

モザイクフィルタ(MosaicFilter)

今回は画面全体にモザイクをかけるモザイクフィルターを作成します。モザイクフィルターでは、画面を指定のサイズ(m×m)に切り分けて、そのサイズの中での色の値の平均値をとり、平均値を新たな色の値とするという流れとなっています。
 Tutorial1Activityクラスと同じ場所にMosaicFilterクラスを作成します。その後、filterメソッドに以下のコードを入力します。
    public int[] filter(int[] imageArray, int width, int height) {
        int size=8;//①
        int xnum=width/size;//②
        int xrest=width%size;
        int ynum=height/size;
        int yrest=height%size;
        int length = width*height;
        int rgb;
        int red,green,blue;

        int rgbarray[][]=new int[3][imageArray.length];
        for(int i =0;i < length;i++){
            rgb = imageArray[i];
            red = (rgb >> 16) & 0xff;
            green = (rgb >> 8) & 0xff;
            blue = (rgb) & 0xff;
            rgbarray[0][i]=red;//③
            rgbarray[1][i]=green;
            rgbarray[2][i]=blue;
        }
        int point=0;
        int rsum,gsum,bsum;
        int[] oimgArray = new int[imageArray.length];
        for(int y=0;y < ynum;y++){
            for(int x=0;x < xnum;x++){
                point=x*size+y*size*width;
                rsum=0;
                gsum=0;
                bsum=0;
                for(int yn=0;yn < size;yn++){
                    for(int xn=0;xn < size;xn++){
                        rsum+=rgbarray[0][point+xn+yn*width];//④
                        gsum+=rgbarray[1][point+xn+yn*width];
                        bsum+=rgbarray[2][point+xn+yn*width];
                    }
                }
                rsum=rsum/(size*size);
                gsum=gsum/(size*size);
                bsum=bsum/(size*size);
                for(int yn=0;yn < size;yn++){
                    for(int xn=0;xn < size;xn++){
                        oimgArray[point+xn+yn*width]=
                                255*16777216+ rsum*65536
                                        + gsum*256+bsum;//⑤
                    }
                }
            }
            if(xrest>0){
                for(int ysize=0;ysize < size; ysize++){
                    for(int rest=0;rest < xrest;rest++){
                        point=xnum*size+(y*size+ysize)*width+rest;
                        oimgArray[point]=imageArray[point];//⑥
                    }
                }
            }
        }
        if(yrest>0){
            for(int rest=0;rest < yrest;rest++){
                for(int x=0;x < width;x++){
                    point=x+(ynum*size+rest)*width;
                    oimgArray[point]=imageArray[point];//⑦
                }
            }
        }
        return oimgArray;
    }

 ①ではモザイクをかけるサイズを指定しています。
 ②では幅と高さを①のサイズで割り、画像の分割数を求めています。
 ③では一度赤緑青の色の値を格納しています。
 ④では①のサイズの領域について色の値の合計数をだし、その後平均値を出しています。
 ⑤では平均値を領域内のすべての画素に適用し、新しい色としています。
 ⑥と⑦では①のサイズが幅や高さを割り切れなかった時の処理を行っています。今回は元の色をそのまま用いるようにしています。

  最後に、 Tutorial1Activityクラスのint imageArray[]=ba2ia(ba);の下に以下の文を記入します。
imageArray=new MosaicFilter().filter(imageArray, imagewidth, imageheight);

以下に実機での実行結果を示します。上が①のサイズが4のときで、下が8のときです。

0 件のコメント:

コメントを投稿