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.


