之前用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);
}
}
程式執行結果
文章標籤
全站熱搜
