Convert bitmap to grayscale using matrix and ColorMatrixColorFilter


This example show how to convert bitmap to grayscale using matrix and ColorMatrixColorFilter. Once photo loaded, touch on the ImageView will show the original photo, touch release to show the grayscale photo.


MainActivity.java
package com.blogspot.android_er.androidimage;

import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.ColorMatrixColorFilter;
import android.graphics.Paint;
import android.net.Uri;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.MotionEvent;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.Toast;

import java.io.FileNotFoundException;

public class MainActivity extends AppCompatActivity {

private static final int RQS_OPEN = 1;
Button buttonOpen;
ImageView imageView;

Bitmap bmNormal, bmGrayScale;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
buttonOpen = (Button) findViewById(R.id.opendocument);
buttonOpen.setOnClickListener(buttonOpenOnClickListener);

imageView = (ImageView)findViewById(R.id.image);
imageView.setOnTouchListener(imageViewOnTouchListener);
}

View.OnTouchListener imageViewOnTouchListener = new View.OnTouchListener(){
@Override
public boolean onTouch(View v, MotionEvent event) {

if(event.getAction() == MotionEvent.ACTION_DOWN){
//user touch on ImageView
if(bmNormal != null){
imageView.setImageBitmap(bmNormal);
}
}else if(event.getAction() == MotionEvent.ACTION_UP){
//user release touch on ImageView
if(bmGrayScale != null){
imageView.setImageBitmap(bmGrayScale);
}
}
return true;
}
};

View.OnClickListener buttonOpenOnClickListener =
new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent();
intent.setAction(Intent.ACTION_OPEN_DOCUMENT);
intent.addCategory(Intent.CATEGORY_OPENABLE);
intent.setType("image/*");
startActivityForResult(intent, RQS_OPEN);
}
};

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (resultCode == RESULT_OK && requestCode == RQS_OPEN) {
Uri dataUri = data.getData();
int w = imageView.getWidth();
int h = imageView.getHeight();
Toast.makeText(MainActivity.this,
dataUri.toString() + " " +
w + " : " + h,
Toast.LENGTH_LONG).show();

try {
bmNormal = bmGrayScale = null;
bmNormal = loadScaledBitmap(dataUri, w, h);
bmGrayScale = getGrayscale(bmNormal);
imageView.setImageBitmap(bmGrayScale);
Toast.makeText(MainActivity.this,
bmGrayScale.getWidth() + " x " + bmGrayScale.getHeight(),
Toast.LENGTH_SHORT).show();
} catch (FileNotFoundException e) {
e.printStackTrace();
Toast.makeText(MainActivity.this, e.getMessage(), Toast.LENGTH_LONG).show();
}
}
}

private Bitmap getGrayscale(Bitmap src){

//Custom color matrix to convert to GrayScale
float[] matrix = new float[]{
0.3f, 0.59f, 0.11f, 0, 0,
0.3f, 0.59f, 0.11f, 0, 0,
0.3f, 0.59f, 0.11f, 0, 0,
0, 0, 0, 1, 0,};

Bitmap dest = Bitmap.createBitmap(
src.getWidth(),
src.getHeight(),
src.getConfig());

Canvas canvas = new Canvas(dest);
Paint paint = new Paint();
ColorMatrixColorFilter filter = new ColorMatrixColorFilter(matrix);
paint.setColorFilter(filter);
canvas.drawBitmap(src, 0, 0, paint);

return dest;
}

/*
reference:
Load scaled bitmap
http://android-er.blogspot.com/2013/08/load-scaled-bitmap.html
*/
private Bitmap loadScaledBitmap(Uri src, int req_w, int req_h) throws FileNotFoundException {

Bitmap bm = null;

// First decode with inJustDecodeBounds=true to check dimensions
final BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeStream(getBaseContext().getContentResolver().openInputStream(src),
null, options);

// Calculate inSampleSize
options.inSampleSize = calculateInSampleSize(options, req_w, req_h);

// Decode bitmap with inSampleSize set
options.inJustDecodeBounds = false;
bm = BitmapFactory.decodeStream(
getBaseContext().getContentResolver().openInputStream(src), null, options);

return bm;
}

public int calculateInSampleSize(BitmapFactory.Options options,
int reqWidth, int reqHeight) {
// Raw height and width of image
final int height = options.outHeight;
final int width = options.outWidth;
int inSampleSize = 1;

if (height > reqHeight || width > reqWidth) {

// Calculate ratios of height and width to requested height and
// width
final int heightRatio = Math.round((float) height
/ (float) reqHeight);
final int widthRatio = Math.round((float) width / (float) reqWidth);

// Choose the smallest ratio as inSampleSize value, this will
// guarantee
// a final image with both dimensions larger than or equal to the
// requested height and width.
inSampleSize = heightRatio < widthRatio ? heightRatio : widthRatio;
}

return inSampleSize;
}
}


layout/activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout

android_layout_width="match_parent"
android_layout_height="match_parent"
android_padding="5dp"
android_background="@android:color/black"
android_orientation="vertical"
tools_context=".MainActivity">

<TextView
android_layout_width="wrap_content"
android_layout_height="wrap_content"
android_layout_gravity="center_horizontal"
android_autoLink="web"
android_text="http://android-er.blogspot.com/"
android_textStyle="bold" />

<Button
android_id="@+id/opendocument"
android_layout_width="match_parent"
android_layout_height="wrap_content"
android_text="Open Document of Image/Video" />

<ImageView
android_id="@+id/image"
android_layout_width="match_parent"
android_layout_height="match_parent" />
</LinearLayout>

Related Posts by Categories

0 comments:

Post a Comment

Blog Archive

Powered by Blogger.