Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to draw the multiple lines with different color and undo,redo the paths in android?

I want to draw multiple lines on the view with different colors and undo,redo the paths in android.

I use the bitmap paint option, each path has a unique color but undo,redo is not working.

Here is my code of bitmappaint:

public MyView(Context context, Object object) {
    super(context);
    setFocusable(true);
    setFocusableInTouchMode(true);
    
    mPath = new Path();
    mPaint = new Paint();
    mPaint.setAntiAlias(true);
    mPaint.setColor(0xFFFFFF00);
    mPaint.setStyle(Paint.Style.STROKE);
    mPaint.setStrokeJoin(Paint.Join.ROUND);
    mPaint.setStrokeCap(Paint.Cap.ROUND);
    mPaint.setStrokeWidth(3);

    mBitmap = Bitmap.createBitmap(320, 480, Bitmap.Config.ARGB_8888);
    mCanvas = new Canvas(mBitmap);
}

protected void onSizeChanged(int w, int h, int oldw, int oldh) 
{
    super.onSizeChanged(w, h, oldw, oldh);
}

protected void onDraw(Canvas canvas) 
{
    canvas.drawBitmap(mBitmap, 0, 0, mBitmapPaint);
    for (Path p : paths)
    {
        canvas.drawPath(p, mPaint);
    }
    canvas.drawPath(mPath, mPaint);
}

public boolean onTouchEvent(MotionEvent event)
{
    float x = event.getX();
    float y = event.getY();
    int action = event.getAction();
    int action1=event.getAction();
    switch (event.getAction())
    {
    case MotionEvent.ACTION_DOWN:
        undonePaths.clear();
        mPath.reset();
        mPath.moveTo(x, y);
        mX = x;
        mY = y;
        startPoint = new PointF(event.getX(), event.getY());
        endPoint = new PointF();
        invalidate();
        //   isDrawing = true;
        break;
    case MotionEvent.ACTION_MOVE:
        float dx = Math.abs(x - mX);
        System.out.println("action move");
        float dy = Math.abs(y - mY);
        if (dx >= TOUCH_TOLERANCE || dy >= TOUCH_TOLERANCE)
        {
            //  currentDrawingPath.path.quadTo(mX,mY,(x + mX)/2, (y + mY)/2);
        }
        mX = x;
        mY = y;
        endPoint.x = event.getX();
        endPoint.y = event.getY();
        isDrawing = true;
        invalidate();
        break;
    case MotionEvent.ACTION_UP:
        mPath.lineTo(mX, mY);
        paths.add(mPath);
        mPath = new Path();
        //  mCanvas.drawPath(mPath, ppaint);
        endPoint.x = event.getX();
        endPoint.y = event.getY();
        isDrawing = false;
        invalidate();
        break;
    default:
        break;
    }       
}

output of bitmappaint canvas

without bitmap using i faced the color problem if i select a blue color for a path means all the previous paths will be changed to blue color;

Here is my code

protected void onDraw(Canvas canvas) 
{
    canvas.drawBitmap(mBitmap, 0, 0, mBitmapPaint);
    for (Path p : paths)
    {
        canvas.drawPath(p, mPaint);
    }
    canvas.drawPath(mPath, mPaint);
}

output of without bitmap using canvas drawing

Can anyone help me to draw multiple paths with different color of unique paths in android?

like image 908
Kevin Rameshwaran Avatar asked Nov 04 '25 17:11

Kevin Rameshwaran


2 Answers

When you handle the MotionEvent.ACTION_UP : you need to save the color used to draw the path with something like this :

case MotionEvent.ACTION_UP:
    paths.add(mPath);
    colorsMap.put(mPath,selectedColor); // store the color of mPath
    ...

Before drawing a path, you need to set the paint color:

protected void onDraw(Canvas canvas) {
    canvas.drawBitmap(mBitmap, 0, 0, mBitmapPaint);
    for (Path p : paths)
    {
        mPaint.setColor(colorsMap.get(p));
        canvas.drawPath(p, mPaint);
    }
    mPaint.setColor(selectedColor);
    canvas.drawPath(mPath, mPaint);
}

And the colorsMap is a simple instance variable:

private Map<Path, Integer> colorsMap = new HashMap<Path, Integer>();    

To implement the Undo/Redo feature, you just have to remove the last element from paths (and store it in a undoneList so that on redo can restore it). see Android Canvas Redo and Undo Operation

like image 117
ben75 Avatar answered Nov 06 '25 09:11

ben75


this working code .I test it on my own app and it is working very good. May be it help u.Please comment on it.

        public class Main extends Activity implements OnColorChangedListener {
        //public static int selectedColor = Color.BLACK;
        public static ArrayList<Path> mMaindialog;
        // private ArrayList<Path> undonePaths;
        // public int selectedcolor;
        private static final String COLOR_PREFERENCE_KEY = "color";
        private FrameLayout relativelayout;
        static String sdpath,location;
        Boolean i;
        // Instance variables
        private Bitmap mBitmap=null;
        Bitmap bitmap;
        private Paint mPaint, mBitmapPaint, mPaint1;
        private MyView mView;
        ImageView idd;
        // private Path mPath;
        int slll = Color.BLACK;
        Bitmap map=ListView5.bMap;
        private Button ClearPaint, Colorpaint;
        Ghostdatabase gost;

        @Override
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.main);
             idd=(ImageView)findViewById(R.id.imageView1);
            relativelayout = (FrameLayout) findViewById(R.id.frameLayout);

            DisplayMetrics metrics = getBaseContext().getResources()
                    .getDisplayMetrics();
            int w = metrics.widthPixels;
            int h = metrics.heightPixels;

            System.out.println(" width " + w);
            System.out.println(" height " + h);



            mView = new MyView(this, w, h);
            mView.setDrawingCacheEnabled(true);

            mPaint = new Paint();
            mPaint.setAntiAlias(true);
            mPaint.setDither(true);
            mPaint.setColor(Color.BLACK);
            mPaint.setStyle(Paint.Style.STROKE);
            mPaint.setStrokeJoin(Paint.Join.ROUND);
            mPaint.setStrokeCap(Paint.Cap.ROUND);
            mPaint.setStrokeWidth(4);

            ClearPaint = (Button) findViewById(R.id.ne);
            ClearPaint.setOnClickListener(new OnClickListener() {

                public void onClick(View v) {
                    // mBitmap.eraseColor(Color.TRANSPARENT);
                    // mPath.reset();
                    // mView.invalidate();

                    mView.onClickUndo();

                }
            });
            Button save22 = (Button) findViewById(R.id.save);
            save22.setOnClickListener(new OnClickListener() {

                @Override
                public void onClick(View v) {
                    // TODO Auto-generated method stub
                    File cacheDir;
                    Toast.makeText(Main.this, "Photo", 500).show();
                    Bitmap icon;
                    relativelayout.setDrawingCacheEnabled(true);

                    icon = Bitmap.createBitmap(relativelayout.getDrawingCache());
                    Bitmap bitmap = icon;
                    relativelayout.setDrawingCacheEnabled(false);
                    // File mFile1 = Environment.getExternalStorageDirectory();
                    Date d = new Date();
                    String fileName = d.getTime() + "mg1.jpg";

                    File storagePath = (Environment.getExternalStorageDirectory());
                    File dest = new File(storagePath + "/CityAppImages");

                    if (!dest.exists()) {
                        dest.mkdirs();

                    }

                    File mFile2 = new File(dest, fileName);
                    sdpath = mFile2.getAbsolutePath();

                    Log.d("qqqqqqqqqqqqqqqqqqqqqqq", "zzzzzzzz" + sdpath);
                    try {
                        FileOutputStream outStream;

                        outStream = new FileOutputStream(mFile2);

                        bitmap.compress(Bitmap.CompressFormat.JPEG, 100, outStream);

                        outStream.flush();

                        outStream.close();
                        Toast.makeText(Main.this, "Photo Saved Sucessfully", 500)
                                .show();
                    } catch (FileNotFoundException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    } catch (IOException e) {

                        // TODO Auto-generated catch block
                        e.printStackTrace();
                        Toast.makeText(Main.this, "Photo Not Saved Sucessfully",
                                500).show();
                    }

                    gost = new Ghostdatabase(Main.this);
                    gost.open();

                    gost.insertTitle(sdpath);
                }
            });

            Button view = (Button) findViewById(R.id.listtt);
            view.setOnClickListener(new OnClickListener() {

                public void onClick(View v) {

                    Intent ii = new Intent(Main.this, ListView5.class);
                    startActivity(ii);

                }
            });

            Button Colorpaint = (Button) findViewById(R.id.Color);
            Colorpaint.setOnClickListener(new OnClickListener() {

                public void onClick(View v) {
                    int color = PreferenceManager.getDefaultSharedPreferences(
                            Main.this).getInt(COLOR_PREFERENCE_KEY, Color.WHITE);
                    // int _color = R.color.red;
                    new ColorPickerDialog(v.getContext(),
                            new OnColorChangedListener() {

                                public void colorChanged(int color) {
                                    mPaint.setColor(color);

                                    slll = color;

                                    Log.i("TAG", "mpaint one" + mPaint);
                                }
                            }, mPaint.getColor()).show();
                    Log.i("TAG", "mpaint two" + mPaint);
                }
            });
            relativelayout.addView(mView);
        }



        // //////////******************* Pinting view
        // *******************///////////////////

        public class MyView extends View implements OnTouchListener {
            private Map<Path, Integer> colorsMap = new HashMap<Path, Integer>();
            private ArrayList<Path> mMaindialog = new ArrayList<Path>();
            private ArrayList<Path> undonePaths = new ArrayList<Path>();
            int colorPicked = slll;
            // Paint mPaint1;

            private Canvas mCanvas;
            private Path mPath;

            public MyView(Context c, int w, int h) {
                super(c);
                if(GlobalVariable.impath==1)
                {
                    Log.d("","111111"+GlobalVariable.impath);
                    System.out.println(GlobalVariable.impath);
                    Intent ii = getIntent();
                     location = ii.getStringExtra("IMAGE");
                    // bitmap.recycle();
                     Log.d("","location"+location);
                     bitmap = BitmapFactory.decodeFile(location);
                     mBitmap = Bitmap.createScaledBitmap(bitmap,300, 300,false);
                     Log.d("hhhhhhhhhhhhhhhssssssss","mBitmap"+mBitmap);
                     //mBitmap = Bitmap.createBitmap(100, 100, Bitmap.Config.ARGB_8888);
                    // idd.setImageBitmap(mBitmap);
                    Log.d("hhhhhhhhhhhhhhhssssssss","GlobalVariable.impath"+GlobalVariable.impath);
                }
                else if(GlobalVariable.impath==2){
                    //bitmap.recycle();
                    Log.d("","22222222222222222222222"+GlobalVariable.impath);
                    bitmap=BitmapFactory.decodeResource(getResources(),R.drawable.base);
                    mBitmap = Bitmap.createScaledBitmap(bitmap,100, 100, false);
                    //mBitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
                    Log.d("hhhhhhhhhhhhhhhssssssss1111111","mBitmap"+mBitmap);
                }



    //          
                mCanvas = new Canvas(mBitmap);
                mPath = new Path();

            }

            @Override
            protected void onSizeChanged(int w, int h, int oldw, int oldh) {
                super.onSizeChanged(w, h, oldw, oldh);

            }

            @Override
            protected void onDraw(Canvas canvas) {

                canvas.drawBitmap(mBitmap, 0, 0, mBitmapPaint);

                for (Path p : mMaindialog) {
                    mPaint.setColor(colorsMap.get(p));
                    canvas.drawPath(p, mPaint);
                }
                mPaint.setColor(slll);
                canvas.drawPath(mPath, mPaint);
            }

            // //////************touching evants for painting**************///////
            private float mX, mY;
            private static final float TOUCH_TOLERANCE = 0;

            private void touch_start(float x, float y) {
                mPath.reset();
                mPath.moveTo(x, y);
                mX = x;
                mY = y;
                undonePaths.clear();
            }

            private void touch_move(float x, float y) {
                float dx = Math.abs(x - mX);
                float dy = Math.abs(y - mY);
                if (dx >= TOUCH_TOLERANCE || dy >= TOUCH_TOLERANCE) {
                    mPath.quadTo(mX, mY, (x + mX) / 2, (y + mY) / 2);
                    mX = x;
                    mY = y;
                }
            }

            private void touch_up() {
                mPath.lineTo(mX, mY);
                // commit the path to our offscreen
                mCanvas.drawPath(mPath, mPaint);
                // kill this so we don't double draw
                mPath = new Path();
                mPath.reset();
                mMaindialog.add(mPath);
            }

            @Override
            public boolean onTouchEvent(MotionEvent event) {
                float x = event.getX();
                float y = event.getY();
                switch (event.getAction()) {
                case MotionEvent.ACTION_DOWN:
                    // touch_start(x, y);
                    // invalidate();
                    undonePaths.clear();
                    mPath.reset();
                    mPath.moveTo(x, y);
                    mX = x;
                    mY = y;
                    invalidate();
                    break;
                case MotionEvent.ACTION_MOVE:
                    // touch_move(x, y);
                    // invalidate();
                    float dx = Math.abs(x - mX);
                    float dy = Math.abs(y - mY);
                    if (dx >= TOUCH_TOLERANCE || dy >= TOUCH_TOLERANCE) {
                        mPath.quadTo(mX, mY, (x + mX) / 2, (y + mY) / 2);
                        mX = x;
                        mY = y;
                    }
                    invalidate();
                    break;
                case MotionEvent.ACTION_UP:
                    // touch_up();
                    // invalidate();
                    mPath.lineTo(mX, mY);
                    mMaindialog.add(mPath);
                    colorsMap.put(mPath, slll);
                    mPath = new Path();
                    mPath.reset();
                    invalidate();
                    break;
                }
                return true;
            } // end of touch events for image

            private Paint createPen(int colorPicked) {
                // TODO Auto-generated method stub
                mPaint1 = new Paint();
                mPaint1.setColor(colorPicked);
                mPaint1.setAntiAlias(true);
                mPaint1.setDither(true);
                mPaint1.setStyle(Paint.Style.STROKE);
                mPaint1.setStrokeJoin(Paint.Join.ROUND);
                mPaint1.setStrokeCap(Paint.Cap.ROUND);
                // mPaint1.setStrokeWidth(3);
                return mPaint1;
            }

            public void onClickRedo() {
                if (undonePaths.size() > 0) {
                    mMaindialog.add(undonePaths.remove(undonePaths.size() - 1));
                    mView.invalidate();

                } else {

                }
                // toast the user
            }

            public void onClickUndo() {
                if (mMaindialog.size() > 0) {
                    undonePaths.add(mView.mMaindialog.remove(mView.mMaindialog
                            .size() - 1));
                    mView.invalidate();
                }

                else {

                }
            }

            @Override
            public boolean onTouch(View arg0, MotionEvent arg1) {
                // TODO Auto-generated method stub
                return false;
            }
        }// end MyView

        @Override
        public void colorChanged(int color) {
            // TODO Auto-generated method stub
            PreferenceManager.getDefaultSharedPreferences(this).edit()
                    .putInt(COLOR_PREFERENCE_KEY, color).commit();
            slll = color;
        }



    }
like image 41
Jelly Bean Avatar answered Nov 06 '25 08:11

Jelly Bean



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!