之前用WindowsAPI寫顯示經由索貝爾算子運算後的點陣圖,這次改用Android程式顯示圖片。運算的方法是一樣,這邊我是定一個myView類別,繼承View,用來處理、顯示圖片。主要要了解的東西有索貝爾算子、Bitmap類別,還有一維陣列當二維陣列用的概念,然後我直接用myView類別產生的物件當做Activity的容器,所以沒動到layout部分。

程式碼如下

MainActivity.java

package com.csy.sobel;

import android.os.Bundle;
import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.view.Menu;
import android.view.MenuItem;
import android.support.v4.app.NavUtils;

public class MainActivity extends Activity {
   
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        myView v = new myView(this);
        v.readBMP("/sdcard/mybmp.bmp");
        setContentView(v);
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.activity_main, menu);
        return true;
    }
    
}

myView.java

package com.csy.sobel;

import android.annotation.SuppressLint;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Bitmap.Config;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.view.View;

public class myView extends View{

    private Bitmap bmp;
    private int height;
    private int width;
    private int srcPixels[];
    private int grayPixels[];
    private int sobelPixels[];
    
    public void readBMP(String path)
    {
         bmp = BitmapFactory.decodeFile(path);
         this.height=bmp.getHeight();
         this.width=bmp.getWidth();
         srcPixels = new int [width*height]; 
         grayPixels = new int [width*height];
         sobelPixels = new int [width*height];
         bmp.getPixels(srcPixels, 0, width, 0, 0, width, height);
         changeToGray(grayPixels, srcPixels);
         changeToSobel(sobelPixels, grayPixels);
    }
    private void changeToGray(int dest[],int src[])
    {
        if (dest.length != src.length)
            return;
        
        int r,g,b;
        
        for (int posY =0 ; posY<this.height; posY++)
        {
            for (int posX =0 ; posX<this.width; posX++)
            {
                r = Color.red(src[posX + posY * height]);
                g = Color.green(src[posX + posY * height]);
                b = Color.blue(src[posX + posY * height]);
                dest[posX + posY * height]=Color.rgb((int)(0.3 * r + 0.59 *g + 0.11 * b), (int)(0.3 * r + 0.59 *g + 0.11 * b), (int)(0.3 * r + 0.59 *g + 0.11 * b));                
            }
        }
    }
    
    private void changeToSobel(int dest[],int src[])
    {
        if (dest.length != src.length)
            return;
        
        final int x_mark[][] = {{-1, 0, 1},
                                {-2, 0, 2},
                                {-1, 0, 1}};
        final int y_mark[][] = {{ 1, 2, 1},
                                { 0, 0, 0},
                                {-1,-2,-1}};
        int x_result[][] = new int [3][3];
        int y_result[][] = new int [3][3];
        int sum, sum_x, sum_y;
        int result[] = new int[src.length];
        int thresold;
        for (int posY =0 ; posY < this.height; posY++) {
            for (int posX =0 ; posX < this.width; posX++) {
                
                for (int ROW = 0; ROW < 3; ROW++) {
                    for (int COL = 0; COL < 3; COL++) {
                        if ((posX + COL) < this.width && (posY + ROW) < this.height) {
                            x_result[ROW][COL] = Color.red(src[(posX + COL) + (posY + ROW)*this.width]) * x_mark[ROW][COL];
                            y_result[ROW][COL] = Color.red(src[(posX + COL) + (posY + ROW)*this.width]) * y_mark[ROW][COL];
                        } else {
                            x_result[ROW][COL] = 0;
                            y_result[ROW][COL] = 0;
                        }
                    }    
                }
                
                sum_x = 0;
                sum_y = 0;
                for (int ROW = 0; ROW < 3; ROW++) {
                    for (int COL = 0; COL < 3; COL++) {
                        sum_x += x_result[ROW][COL];
                        sum_y += y_result[ROW][COL];
                    }
                }
                result[posX + posY * height] = Math.abs(sum_x) + Math.abs(sum_y);    
            }
        }
        sum = 0;
        for (int i = 0; i < (this.width * this.height); i++)
            sum+=result[i];
        thresold = sum / (this.width * this.height);
        for (int i = 0; i < (this.width * this.height); i++)
        {
            if(result[i] >= thresold)
                dest[i] = Color.rgb(255, 255, 255);
            else
                dest[i] = Color.rgb(0, 0, 0);
        }
    
    }
    
    
    
    public myView(Context context) 
    {
        super(context);
        // TODO Auto-generated constructor stub
    }
    @SuppressLint("DrawAllocation")
    @Override
    protected void onDraw(Canvas canvas)
    {
         Bitmap bmp = Bitmap.createBitmap(sobelPixels, width, height, Config.ARGB_8888);
         canvas.drawBitmap(bmp, 0, 0,null);
    }

}

程式執行結果 

文章標籤
全站熱搜
創作者介紹
創作者 jeff810123 的頭像
jeff810123

在我心中有一個夢

jeff810123 發表在 痞客邦 留言(0) 人氣(247)