Conver gray scale image to color image

Problems with Canvas, OpenGL, etc...

Conver gray scale image to color image

Postby shialesh » Mon Nov 15, 2010 9:55 am

Hi all,

i am developing on application which will convert original image to gray scal image.

Now when user move brush on it the image is conver into color image using bitmap masking.

But i am not able to convert original color image into gray scale when user move brush on original image. i am able to convert whole image but not able to conver perticular portion of image into gray scale.

following is the code which i have written.

import java.io.FileNotFoundException;
import java.io.InputStream;
import java.util.ArrayList;

import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
import android.content.ContentResolver;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.BlurMaskFilter;
import android.graphics.Canvas;
import android.graphics.ColorMatrix;
import android.graphics.ColorMatrixColorFilter;
import android.graphics.MaskFilter;
import android.graphics.Paint;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffXfermode;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.provider.MediaStore.Images;
import android.view.KeyEvent;
import android.view.Menu;
import android.view.MenuItem;
import android.view.MotionEvent;
import android.view.View;
import android.view.Window;
import android.view.MenuItem.OnMenuItemClickListener;
import android.view.View.OnClickListener;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ProgressBar;

import com.dashofcolor.data.ConstantData;
import com.dashofcolor.util.IOUtils;

/**
* This is the main activity of this app. user can process image, can change tools, save image,
* undo changes, select new image, email it etc.
*
* @author shpatel
*
*/

public class HomeScreen extends Activity{

private LinearLayout lnrImageContainer = null;
private CustomView mCustomView = null;
private final int TAB_TOOLS = 1;
private final int TAB_FINISH = 2;
private final int SCALE_GRAY = 1;
private final int SCALE_COLOR = 2;
private int WIDTH = 0;
private int HEIGHT = 0;
private static int scaleType = 1;
private static int brushSize = 2;
private int currentTab = 1;
private ProgressBar progressBar = null;
private Bitmap mOriginalBitmap = null;
private Handler mHandler = null;
private LinearLayout popup = null;
private Animation animShow = null, animHide = null;
private String savedImageURL = "";
private boolean savedFlag = false;
private boolean zoomFlag = false;

private Button btnColor = null, btnGray = null, btnBrush = null, btnCancel = null;

private ArrayList<ArrayList<Float[]>> undoList = null;
private DBHelper db = null;

@Override
public boolean onPrepareOptionsMenu(Menu menu) {

menu.clear();
closePopup();

// add menu on screen
MenuItem mnuImages = menu.add(0, 1, 0, "Images");
mnuImages.setIcon(getResources().getDrawable(R.drawable.tab_images_off));
MenuItem mnuUndo = menu.add(0, 1, 0, "Undo");
mnuUndo.setIcon(getResources().getDrawable(R.drawable.tab_undo_off));
MenuItem mnuTools = menu.add(0, 1, 0, "Tools");
mnuTools.setIcon(getResources().getDrawable(R.drawable.tab_tools_off));
MenuItem mnuFinish = menu.add(0, 1, 0, "Finish");
mnuFinish.setIcon(getResources().getDrawable(R.drawable.tab_finish_off));
MenuItem mnuFreeApps = menu.add(0, 1, 0, "Free Apps!");
mnuFreeApps.setIcon(getResources().getDrawable(R.drawable.tab_free_off));

mnuImages.setOnMenuItemClickListener(new OnMenuItemClickListener(){
public boolean onMenuItemClick(MenuItem item) {

closePopup();

Intent intent = new Intent();
intent.setType("image/*");
intent.setAction(Intent.ACTION_GET_CONTENT);
startActivityForResult(Intent.createChooser(intent,"Gallery"),1);
return false;
}});

mnuUndo.setOnMenuItemClickListener(new OnMenuItemClickListener(){
public boolean onMenuItemClick(MenuItem item) {

closePopup();

mCustomView.performUndo(true);
return false;
}});

mnuTools.setOnMenuItemClickListener(new OnMenuItemClickListener(){
public boolean onMenuItemClick(MenuItem item) {

btnBrush.setVisibility(View.GONE);
currentTab = TAB_TOOLS;
btnColor.setText("Color");
btnGray.setText("Gray");
btnBrush.setText("Brush Size");
popup.setVisibility(View.VISIBLE);
popup.startAnimation( animShow );
btnCancel.setEnabled(true);
return false;
}});

mnuFinish.setOnMenuItemClickListener(new OnMenuItemClickListener(){
public boolean onMenuItemClick(MenuItem item) {

btnBrush.setVisibility(View.VISIBLE);
currentTab = TAB_FINISH;
btnColor.setText("New Session");
btnGray.setText("Save");
btnBrush.setText("Send Mail");
popup.setVisibility(View.VISIBLE);
popup.startAnimation( animShow );
btnCancel.setEnabled(true);
return false;
}});

mnuFreeApps.setOnMenuItemClickListener(new OnMenuItemClickListener(){
public boolean onMenuItemClick(MenuItem item) {

closePopup();
return false;
}});

return true;
}

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// set layout
setContentView(R.layout.homescreen);

try {

SharedPreferences settings = getSharedPreferences(ConstantData.SHARED_PREF_NAME, MODE_PRIVATE);
brushSize = settings.getInt("brushSize", 2);

String uri = settings.getString("uri", null);
ConstantData.IMAGE_URI = Uri.parse(uri);

mHandler = new Handler();
undoList = new ArrayList<ArrayList<Float[]>>();

db = new DBHelper(this);
db.open();

// get views reference
lnrImageContainer = (LinearLayout) findViewById(R.id.lnrImageContainer);
progressBar = (ProgressBar) findViewById(R.id.progressBar);

popup = (LinearLayout) findViewById(R.id.lnrPopup);
popup.bringToFront();

mHandler.postDelayed(new Runnable(){
public void run() {

try {

WIDTH = lnrImageContainer.getWidth();
HEIGHT = lnrImageContainer.getHeight();

loadBitmap();

} catch (Exception e) {
showMessage("Error in Bitmap", e.toString());
e.printStackTrace();
}

mCustomView = new CustomView(HomeScreen.this);
lnrImageContainer.addView(mCustomView);
progressBar.setVisibility(View.GONE);
mCustomView.setDrawingCacheEnabled(true);

}}, 500);

undoList = db.getListData();

initPopup();

} catch (Exception e) {
showMessage("Error in onCreate", e.toString()+" : "+e.getMessage());
}

}



// call when child activity will be closed
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {

if(requestCode == 1 && resultCode == RESULT_OK){

try {
ConstantData.IMAGE_URI = data.getData();

loadBitmap();
undoList.clear();

mCustomView = new CustomView(HomeScreen.this);
lnrImageContainer.removeAllViews();
lnrImageContainer.addView(mCustomView);

SharedPreferences settings = getSharedPreferences(ConstantData.SHARED_PREF_NAME, MODE_PRIVATE);
Editor editor = settings.edit();
editor.putString("uri", ConstantData.IMAGE_URI.toString());
editor.commit();

} catch (Exception e) {
showMessage("Error in Bitmap", e.toString());
e.printStackTrace();
}
}
}

private void loadBitmap(){

try {

ContentResolver cr = HomeScreen.this.getContentResolver();
InputStream is = cr.openInputStream(ConstantData.IMAGE_URI);
BitmapFactory.Options option = new BitmapFactory.Options();
option.inSampleSize = 2;
// option.inPurgeable=true;
mOriginalBitmap = BitmapFactory.decodeStream(is, null, option);
is.close();
cr.cancelSync(ConstantData.IMAGE_URI);
mOriginalBitmap = IOUtils.resizeBitmap(mOriginalBitmap, WIDTH, HEIGHT);

} catch (FileNotFoundException e) {
showMessage("Error", "Image is not available, please select new image");
} catch (OutOfMemoryError e) {
showMessage("Error in loadBitmap", e.toString());
} catch (Exception e) {
showMessage("Error in loadBitmap", e.toString());
}
}

private void initPopup() throws Exception {

// Start out with the popup initially hidden.
popup.setVisibility(View.GONE);

animShow = AnimationUtils.loadAnimation( this, R.anim.popup_show);
animHide = AnimationUtils.loadAnimation( this, R.anim.popup_hide);

btnColor = (Button) findViewById(R.id.btnColor);
btnGray = (Button) findViewById(R.id.btnGray);
btnBrush = (Button) findViewById(R.id.btnBrushSize);
btnCancel = (Button) findViewById(R.id.btnCancel);

// handle click of color button of popup
btnColor.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
popup.startAnimation( animHide );
btnCancel.setEnabled(false);
popup.setVisibility(View.GONE);

if(currentTab == TAB_TOOLS){
scaleType = SCALE_COLOR;
}else if(currentTab == TAB_FINISH){

SharedPreferences settings = getSharedPreferences(ConstantData.SHARED_PREF_NAME, MODE_PRIVATE);
Editor editor = settings.edit();
editor.putString("uri", null);
editor.commit();

Intent i = new Intent(HomeScreen.this, ChoosePicture.class);
startActivity(i);
finish();

}
}});

// handle click of gray button of popup
btnGray.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
popup.startAnimation( animHide );
btnCancel.setEnabled(false);
popup.setVisibility(View.GONE);

if(currentTab == TAB_TOOLS){
scaleType = SCALE_GRAY;
}else if(currentTab == TAB_FINISH){

saveBitmap();
}
}});

// handle click of brush size button of popup
btnBrush.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
popup.startAnimation( animHide );
btnCancel.setEnabled(false);
popup.setVisibility(View.GONE);

if(currentTab == TAB_TOOLS){
try {
displayBrushDialog();
} catch (Exception e) {
showMessage("Error in BrushDialog", e.toString()+" : "+e.getMessage());
}
}else if(currentTab == TAB_FINISH){
sendMail();
}
}});

// handle click of cancel button of popup
btnCancel.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {

closePopup();
}});
}

private void closePopup(){

final Animation animHide = AnimationUtils.loadAnimation( this, R.anim.popup_hide);

if(popup.getVisibility() == View.VISIBLE){

popup.startAnimation( animHide );
popup.setVisibility(View.GONE);
}
}

private void displayBrushDialog() throws Exception{

final Dialog dialog = new Dialog(this, R.style.Theme_CustomDialog);
dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
dialog.setContentView(R.layout.brush_dialog);
dialog.setCancelable(true);
// dialog.setCanceledOnTouchOutside(false);

final Bitmap btmBrush = BitmapFactory.decodeResource(getResources(), R.drawable.brush);
final Button btnPlus = (Button) dialog.findViewById(R.id.btnPlus);
final Button btnMinus = (Button) dialog.findViewById(R.id.btnMinus);
Button btnOK = (Button) dialog.findViewById(R.id.btnOK);
final ImageView imvBrush = (ImageView) dialog.findViewById(R.id.imvBrush);
imvBrush.setImageBitmap(IOUtils.resizeBitmap(btmBrush, brushSize * 20, brushSize *20));

if(brushSize == 1){
btnMinus.setBackgroundResource(R.drawable.btn_minus_off);
btnMinus.setEnabled(false);
}else if(brushSize == 5){
btnPlus.setBackgroundResource(R.drawable.btn_plus_off);
btnPlus.setEnabled(false);
}

btnPlus.setOnClickListener(new OnClickListener(){
public void onClick(View v) {
brushSize++;
imvBrush.setImageBitmap(IOUtils.resizeBitmap(btmBrush, brushSize * 20, brushSize *20));

if(brushSize == 5){
btnPlus.setEnabled(false);
btnPlus.setBackgroundResource(R.drawable.btn_plus_off);
}

if(!btnMinus.isEnabled()){
btnMinus.setEnabled(true);
btnMinus.setBackgroundResource(R.drawable.btn_minus_on);
}
}});

btnMinus.setOnClickListener(new OnClickListener(){
public void onClick(View v) {
brushSize--;
imvBrush.setImageBitmap(IOUtils.resizeBitmap(btmBrush, brushSize * 20, brushSize *20));

if(brushSize == 1){
btnMinus.setEnabled(false);
btnMinus.setBackgroundResource(R.drawable.btn_minus_off);
}

if(!btnPlus.isEnabled()){
btnPlus.setEnabled(true);
btnPlus.setBackgroundResource(R.drawable.btn_plus_on);
}
}});

btnOK.setOnClickListener(new OnClickListener(){

public void onClick(View v) {

SharedPreferences settings = getSharedPreferences(ConstantData.SHARED_PREF_NAME, MODE_PRIVATE);
Editor editor = settings.edit();
editor.putInt("brushSize", brushSize);
editor.commit();
dialog.dismiss();
}});

dialog.show();
}

private void saveBitmap(){

try {

if(!savedFlag){

// Bitmap savedBitmap = mCustomView.getDrawingCache();

Bitmap savedBitmap= Bitmap.createBitmap(mCustomView.getWidth(), mCustomView.getHeight(), Bitmap.Config.RGB_565);
mCustomView.draw(new Canvas(savedBitmap));

savedImageURL = Images.Media.insertImage(getContentResolver(), savedBitmap, "DashOfColor_"+System.currentTimeMillis(), null);
getContentResolver().cancelSync(Uri.parse(savedImageURL));
savedFlag = true;

showMessage("Save", "Your new image is saved to album successful!");

}else{
showMessage("Already Saved", "No changes made after last save!");
}

} catch (Exception e) {
showMessage("Error in saveBitmap", e.toString());
}

}

private void sendMail(){

if (!savedFlag) {

Bitmap bitmap = Bitmap.createBitmap(mCustomView.getWidth(), mCustomView.getHeight(), Bitmap.Config.ARGB_8888);
mCustomView.draw(new Canvas(bitmap));

savedImageURL = Images.Media.insertImage(getContentResolver(), bitmap, "DashOfColor_" + System.currentTimeMillis(), null);
getContentResolver().cancelSync(Uri.parse(savedImageURL));

savedFlag = true;
}

Intent sendIntent = new Intent(Intent.ACTION_SEND);
sendIntent.putExtra(Intent.EXTRA_SUBJECT, "Dash of Color");
sendIntent.putExtra(Intent.EXTRA_TEXT, "Image sent from Dash of Color Android Application");
sendIntent.putExtra(Intent.EXTRA_STREAM,Uri.parse(savedImageURL));
sendIntent.setType("message/rfc822");
startActivityForResult((Intent.createChooser(sendIntent, "Send Mail")),3);
}

private void showMessage(String title,String message){

AlertDialog.Builder b = new AlertDialog.Builder(HomeScreen.this);
AlertDialog a= b.create();
a.setTitle(title);
a.setMessage(message);
a.setButton("Ok",new DialogInterface.OnClickListener(){
public void onClick(DialogInterface arg0, int arg1) {

}});
a.show();
}

//********************************************
// CustomView
//********************************************

private class CustomView extends View{

private Bitmap mBitmap = null;
private Canvas mCanvas = null;
private Paint mErasePaint = null;
private MaskFilter mBlur = null;

private float x = 0, y = 0;
private float mX = 0, mY = 0;
private ArrayList<Float[]> line = null;

public CustomView(Context context) {
super(context);

mBlur = new BlurMaskFilter(10, BlurMaskFilter.Blur.NORMAL);

mErasePaint = new Paint();
// Set eraser paint properties
mErasePaint.setAlpha(0);
mErasePaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_IN));
mErasePaint.setAntiAlias(true);
mErasePaint.setStyle(Paint.Style.STROKE);
mErasePaint.setStrokeJoin(Paint.Join.ROUND);
mErasePaint.setStrokeCap(Paint.Cap.ROUND);
mErasePaint.setStrokeWidth(30);
mErasePaint.setMaskFilter(mBlur);

convertToGrayScale();

performUndo(false);

}

@Override
protected void onDraw(Canvas canvas) {

if(mOriginalBitmap != null){
canvas.drawBitmap(mOriginalBitmap, 0, 0, new Paint());
}

canvas.drawBitmap(mBitmap, 0, 0, new Paint());

canvas.drawBitmap(BitmapFactory.decodeResource(getResources(), R.drawable.zoom_out), 5, HEIGHT-28, new Paint());
canvas.drawBitmap(BitmapFactory.decodeResource(getResources(), R.drawable.zoom_in), WIDTH-28, HEIGHT-28, new Paint());

if(zoomFlag){
canvas.drawBitmap(BitmapFactory.decodeResource(getResources(), R.drawable.zoom_drag), x-53, y-53, new Paint());
}
}


@Override
public boolean onTouchEvent(MotionEvent event) {

x = event.getX();
y = event.getY();

savedFlag = false;

switch (event.getAction()) {

case MotionEvent.ACTION_DOWN:
mX = x;
mY = y;

if(x > WIDTH-28 && y > HEIGHT-28 ){

zoomFlag = true;

}else if(x < 28 && y > HEIGHT-28 ){

// to do

}else{

line = new ArrayList<Float[]>();
Float[] xy = new Float[]{x,y};
// Log.i("down-xy", xy[0]+" | "+xy[1]);
line.add(xy);
}
invalidate();
break;

case MotionEvent.ACTION_MOVE:


if(!zoomFlag){

mCanvas.drawLine(mX, mY, x, y, mErasePaint);

Float[] xy = new Float[]{x,y};
// Log.i("move-xy", xy[0]+" | "+xy[1]);
line.add(xy);
}

invalidate();
mX = x;
mY = y;
break;

case MotionEvent.ACTION_UP:

if(zoomFlag){
zoomFlag = false;
}else{

// Log.i("up-xy", "added-"+line.size());
undoList.add(line);
}
invalidate();
break;
}

return true;
}

private void convertToGrayScale() {

Paint paintGray = new Paint();
ColorMatrix cm = new ColorMatrix();
cm.setSaturation(0);
ColorMatrixColorFilter cmcf = new ColorMatrixColorFilter(cm);
paintGray.setColorFilter(cmcf);

mBitmap = Bitmap.createBitmap(WIDTH, HEIGHT, Bitmap.Config.ARGB_8888);
mCanvas = new Canvas();
mCanvas.setBitmap(mBitmap);

if(mOriginalBitmap != null){
mCanvas.drawBitmap(mOriginalBitmap, 0, 0, paintGray);
}

invalidate();
}

public void performUndo(boolean undo){

try {

convertToGrayScale();

// Log.i("undo list size", ""+undoList.size());

if(undoList.size() > 0){

if(undo){
undoList.remove(undoList.size()-1);
}

for(int i=0;i<undoList.size();i++){

ArrayList<Float[]> line = undoList.get(i);
// Log.i("line size", ""+line.size());

for(int j=0;j<line.size();j++){

Float[] xy = line.get(j);

if(j == 0){
mX = xy[0];
mY = xy[1];
}

mCanvas.drawLine(mX, mY, xy[0], xy[1], mErasePaint);
// Log.i("line", mX+" | "+mY+" | "+xy[0]+" | "+xy[1]);

invalidate();
mX = xy[0];
mY = xy[1];
}
}
}

} catch (Exception e) {
showMessage("Error in undo", e.toString());
}
}
}


@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {

if(keyCode == KeyEvent.KEYCODE_BACK){

if(popup.getVisibility() == View.VISIBLE){
closePopup();
}else{
finish();
}
}
return false;
}


@Override
protected void onDestroy() {
super.onDestroy();

if(undoList != null){
db.insertListData(undoList);
}

db.close();
}

}


Please provide any solution if anybody knows.
shialesh
Freshman
Freshman
 
Posts: 9
Joined: Thu Jul 30, 2009 11:11 am

Top

Re: Conver gray scale image to color image

Postby Schermvlieger » Tue Nov 16, 2010 10:33 am

An idea:

Load the bitmap 2 times; one in grayscale and one in color. Display them on top of each other. Use the Alpha channel of the "paintbrush" to create holes in the front image. Would that work?
Schermvlieger
Senior Developer
Senior Developer
 
Posts: 159
Joined: Fri Feb 26, 2010 1:37 pm

Top

Return to Android 2D/3D Graphics - OpenGL Problems

Who is online

Users browsing this forum: No registered users and 2 guests