May 18, 2012

Android image processing - Gaussian Blur

Read it first: Image processing on Android, the basic logic of Convolution Matrix.

In this example, the Sample Gaussian matrix from the article of Wikipedia - Gaussian blur is used as the 7 x 7 kernal to convolve image to apply Gaussian blur.

Gaussian Blur


package com.AndroidImageProcessing;

import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Color;
import android.os.Bundle;
import android.os.Handler;
import android.view.View;
import android.widget.ImageView;
import android.widget.ProgressBar;

public class AndroidImageProcessingActivity extends Activity {
 
 final static int KERNAL_WIDTH = 7;
 final static int KERNAL_HEIGHT = 7;

 int[][] kernal_GaussianMatrix = {
   {67,   2292,   19117,   38771,   19117,   2292,   67  },
   {2292,   78633,   655965,  1330373,  655965,  78633,   2292 },
   {19117,  655965,  5472157,  11098164,  5472157,  655965,  19117 },
   {38771,  1330373,  11098164,  22508352,  11098164,  1330373,  38771 },
   {19117,  655965,  5472157,  11098164,  5472157,  655965,  19117 },
   {2292,   78633,   655965,  1330373,  655965,  78633,   2292 },
   {67,   2292,   19117,   38771,   19117,   2292,   67  }
 };
 
 ImageView imageSource, imageAfter;
 Bitmap bitmap_Source;
 ProgressBar progressBar;
 
 private Handler handler;
 Bitmap afterProcess;
 
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        imageSource = (ImageView)findViewById(R.id.imageSource);
        imageAfter = (ImageView)findViewById(R.id.imageAfter);
        progressBar = (ProgressBar)findViewById(R.id.progressBar);
        
        bitmap_Source = BitmapFactory.decodeResource(getResources(), R.drawable.testpicture);

        handler = new Handler();
        StratBackgroundProcess();
    }
    
    private void StratBackgroundProcess(){
     
     Runnable runnable = new Runnable(){

   @Override
   public void run() {
    afterProcess = processingBitmap(bitmap_Source, kernal_GaussianMatrix);
    
    handler.post(new Runnable(){

     @Override
     public void run() {
      progressBar.setVisibility(View.GONE);
      imageAfter.setImageBitmap(afterProcess);
     }
     
    });
   }
     };
     new Thread(runnable).start();
    }
    
    private Bitmap processingBitmap(Bitmap src, int[][] knl){
     Bitmap dest = Bitmap.createBitmap(
       src.getWidth(), src.getHeight(), src.getConfig());
     
     int bmWidth = src.getWidth();
     int bmHeight = src.getHeight();
     int bmWidth_MINUS_6 = bmWidth - 6;
     int bmHeight_MINUS_6 = bmHeight - 6;
     int bmWidth_OFFSET_3 = 3;
     int bmHeight_OFFSET_3 = 3;
     
     for(int i = bmWidth_OFFSET_3; i <= bmWidth_MINUS_6; i++){
      for(int j = bmHeight_OFFSET_3; j <= bmHeight_MINUS_6; j++){
       
       //get the surround 7*7 pixel of current src[i][j] into a matrix subSrc[][]
       int[][] subSrc = new int[KERNAL_WIDTH][KERNAL_HEIGHT];
       for(int k = 0; k < KERNAL_WIDTH; k++){
        for(int l = 0; l < KERNAL_HEIGHT; l++){
         subSrc[k][l] = src.getPixel(i-bmWidth_OFFSET_3+k, j-bmHeight_OFFSET_3+l);
        }
       }
       
       //subSum = subSrc[][] * knl[][]
       long subSumR = 0;
       long subSumG = 0;
       long subSumB = 0;

       for(int k = 0; k < KERNAL_WIDTH; k++){
        for(int l = 0; l < KERNAL_HEIGHT; l++){
         subSumR += (long)(Color.red(subSrc[k][l])) * (long)(knl[k][l]);
         subSumG += (long)(Color.green(subSrc[k][l])) * (long)(knl[k][l]);
         subSumB += (long)(Color.blue(subSrc[k][l])) * (long)(knl[k][l]);
        }
       }
       
       subSumR = subSumR/100000000;
       subSumG = subSumG/100000000;
       subSumB = subSumB/100000000;

       if(subSumR <0){
        subSumR = 0;
       }else if(subSumR > 255){
        subSumR = 255; 
       }
       
       if(subSumG <0){
        subSumG = 0;
       }else if(subSumG > 255){
        subSumG = 255;
       }
       
       if(subSumB <0){
        subSumB = 0;
       }else if(subSumB > 255){
        subSumB = 255;
       }

       dest.setPixel(i, j, Color.argb(
         Color.alpha(src.getPixel(i, j)), 
         (int)subSumR, 
         (int)subSumG, 
         (int)subSumB));
      } 
     }
     
     return dest;
    }

}


<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical" >

    <TextView
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="@string/hello" />
    <ScrollView 
        android:layout_width="fill_parent"
        android:layout_height="fill_parent">
        <LinearLayout 
            android:layout_width="fill_parent"
         android:layout_height="fill_parent"
         android:orientation="vertical" >
         <TextView
             android:layout_width="fill_parent"
             android:layout_height="wrap_content"
             android:text="Original" />
      <ImageView
          android:id="@+id/imageSource" 
          android:layout_width="wrap_content"
          android:layout_height="wrap_content" 
          android:src="@drawable/testpicture"/>
      <TextView
             android:layout_width="fill_parent"
             android:layout_height="wrap_content"
             android:text="Result" />
      <FrameLayout 
          android:layout_width="wrap_content"
          android:layout_height="wrap_content">
          <ImageView
              android:id="@+id/imageAfter" 
              android:layout_width="wrap_content"
              android:layout_height="wrap_content"/>
          <ProgressBar
              android:id="@+id/progressBar"
              style="?android:attr/progressBarStyleLarge"
              android:layout_width="wrap_content"
              android:layout_height="wrap_content"/>
      </FrameLayout>
      
     </LinearLayout>
    </ScrollView>

</LinearLayout>


No comments:

Post a Comment

Infolinks In Text Ads