Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to save the edited canvas to image as original image size in android

I am trying to draw on the image and save the image. Now I can succesfully draw the on the image. But I am facing 2 problems. When I draw on the image it allow to draw out side of the image also. I want draw on the image only. The second issue is when I save the image it getting struched. I want to save the image as original size. Please help me to resolve my problems.

Here I post my entire code.

    public class DrawingPaint extends View implements View.OnTouchListener {

    private Canvas mCanvas;
    private Path mPath;
    private Paint mPaint, mBitmapPaint;
    public ArrayList<PathPoints> paths = new ArrayList<PathPoints>();
    private ArrayList<PathPoints> undonePaths = new ArrayList<PathPoints>();
    private Bitmap mBitmap;
    private int color;
    private int x, y;
    private String textToDraw = null;
    private boolean isTextModeOn = false;
    int lastColor = 0xFFFF0000;
    static final float STROKE_WIDTH = 15f;

    public DrawingPaint(Context context/*, int color*/) {
        super(context);
        //this.color = color;
        setFocusable(true);
        setFocusableInTouchMode(true);

        this.setOnTouchListener(this);

        mBitmapPaint = new Paint(Paint.DITHER_FLAG);
        /*mPaint = new Paint();
        mPaint.setAntiAlias(true);
        mPaint.setDither(true);
        mPaint.setStyle(Paint.Style.STROKE);
        mPaint.setStrokeJoin(Paint.Join.ROUND);
        mPaint.setStrokeCap(Paint.Cap.ROUND);
        mPaint.setStrokeWidth(STROKE_WIDTH);
        mPaint.setTextSize(30);

        mPath = new Path();
        paths.add(new PathPoints(mPath, color, false));
        mCanvas = new Canvas();*/
    }

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

    public void setColor(int color) {

        mPaint = new Paint();
        this.color = color;
        mPaint.setAntiAlias(true);
        mPaint.setDither(true);
        mPaint.setColor(color);
        mPaint.setStyle(Paint.Style.STROKE);
        mPaint.setStrokeJoin(Paint.Join.ROUND);
        mPaint.setStrokeCap(Paint.Cap.ROUND);
        mPaint.setStrokeWidth(STROKE_WIDTH);
        mPaint.setTextSize(30);

       mPath = new Path();
       paths.add(new PathPoints(mPath, color, false));
       mCanvas = new Canvas();

    }

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        // mBitmap = AddReportItemActivity.mPhoto;
        mBitmap = CustomGalleryHandler.getmInstance().getBitmapSend();
        float xscale = (float) w / (float) mBitmap.getWidth();
        float yscale = (float) h / (float) mBitmap.getHeight();
        if (xscale > yscale) // make sure both dimensions fit (use the
            // smaller scale)
            xscale = yscale;
        float newx = (float) w * xscale;
        float newy = (float) h * xscale; // use the same scale for both
        BitmapFactory.Options options = new BitmapFactory.Options();
        options.inJustDecodeBounds = true;
        BitmapFactory.decodeFile(new File(PreferenceForCustomCamera.getInstance().getImagePathForGalleryFullScreen()).getAbsolutePath(), options);
        int imageHeight = options.outHeight;
        int imageWidth = options.outWidth;

        m = new Matrix();
        RectF drawableRect = new RectF(0, 0, imageWidth, imageHeight);
        RectF viewRect = new RectF(0, 0, w, h);
        m.setRectToRect(drawableRect, viewRect, Matrix.ScaleToFit.CENTER);
        mBitmap = Bitmap.createBitmap(mBitmap,0,0,imageWidth,
            imageHeight, m,true);
    }

    @Override
    protected void onDraw(Canvas canvas) {
    float[] pts = {0, 0};
    m.mapPoints(pts);
    canvas.drawBitmap(mBitmap, pts[0], pts[1], mBitmapPaint);
        //canvas.drawBitmap(mBitmap, 0, 0, mBitmapPaint);
        for (PathPoints p : paths) {
            mPaint.setColor(p.getColor());
            Log.v("", "Color code : " + p.getColor());
            if (p.isTextToDraw()) {
                canvas.drawText(p.textToDraw, p.x, p.y, mPaint);
            } else {
                canvas.drawPath(p.getPath(), mPaint);
            }
        }
    }

    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;
    }

    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();
        paths.add(new PathPoints(mPath, color, false));

    }

    private void drawText(int x, int y) {

        this.x = x;
        this.y = y;
        paths.add(new PathPoints(color, textToDraw, true, x, y));
        // mCanvas.drawText(textToDraw, x, y, mPaint);
    }

    @Override
    public boolean onTouch(View arg0, MotionEvent event) {
        float x = event.getX();
        float y = event.getY();

        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                if (!isTextModeOn) {
                    touch_start(x, y);
                    invalidate();
                }
                break;
            case MotionEvent.ACTION_MOVE:
                if (!isTextModeOn) {
                    touch_move(x, y);
                    invalidate();
                }
                break;
            case MotionEvent.ACTION_UP:
                if (isTextModeOn) {
                    drawText((int) x, (int) y);
                    invalidate();
                } else {
                    touch_up();
                    invalidate();
                }
                break;
        }
        return true;
    }

    public void onClickUndo() {
        try {
            if (paths.size() > 0) {
                undonePaths.add(paths.remove(paths.size() - 1));
                invalidate();
            } else {

            }
        } catch (Exception e) {
            e.toString();
        }

    }

    public void onClickRedo() {
        try {

           if (undonePaths.size() > 0) {
                paths.add(undonePaths.remove(undonePaths.size() - 1));
                invalidate();
            } else {

            }
        } catch (Exception e) {
            e.toString();
        }
    }
}

My Main Activity is:

public class GalleryImageFullScreen extends Activity implements View.OnClickListener {


private ImageView mFullScreenImage;
private ImageView /*mWhiteColor,*//* mGreenColor, mSkyBlueColor, mYellowColor, mRedColor, mBlackColor,*/ mUndoIcon,
mPaintImageSave, mPaintImageDelete, mRedoIcon;
RoundedImageView mWhiteColor, mGreenColor, mSkyBlueColor, mYellowColor, mRedColor, mBlackColor;
// private Signature mSignature;
private RelativeLayout mDrawLayout;
private DrawingPaint mDrawViewSignature;
private AlertDialog  mAlertDialog = null;
Bitmap bitmapss;

@Override
protected void onCreate(Bundle savedInstanceState) {
    requestWindowFeature(Window.FEATURE_NO_TITLE);
    setContentView(R.layout.gallery_fullscreen);
    super.onCreate(savedInstanceState);

    mUndoIcon =(ImageView)findViewById(R.id.erase_icon);
    mFullScreenImage=(ImageView)findViewById(R.id.img_fullscreen);
    mDrawLayout=(RelativeLayout)findViewById(R.id.img_fullscreen_layout);
    mPaintImageSave=(ImageView)findViewById(R.id.paint_img_save);
    mPaintImageDelete=(ImageView)findViewById(R.id.paint_img_delete);
    mRedoIcon=(ImageView)findViewById(R.id.img_redo);
    mWhiteColor.setOnClickListener(this);
    mGreenColor.setOnClickListener(this);
    mSkyBlueColor.setOnClickListener(this);
    mYellowColor.setOnClickListener(this);
    mRedColor.setOnClickListener(this);
    mBlackColor.setOnClickListener(this);
    mUndoIcon.setOnClickListener(this);
    mPaintImageSave.setOnClickListener(this);
    mPaintImageDelete.setOnClickListener(this);
    mRedoIcon.setOnClickListener(this);
   // mSignature = new Signature(GalleryImageFullScreen.this, null);

    try {
        Intent i=getIntent();
        Bitmap  image = null;

        image = BitmapFactory.decodeFile(PreferenceForCustomCamera.getInstance().getImagePathForGalleryFullScreen());
                CustomGalleryHandler.getmInstance().setBitmapSend(image);

        BitmapFactory.Options options = new BitmapFactory.Options();
        options.inJustDecodeBounds = true;
        BitmapFactory.decodeFile(new File(PreferenceForCustomCamera.getInstance().getImagePathForGalleryFullScreen()).getAbsolutePath(), options);
        int imageHeight = options.outHeight;
        int imageWidth = options.outWidth;

        mDrawLayout.getLayoutParams().width = imageWidth;
        mDrawLayout.getLayoutParams().height = imageHeight;
        //RelativeLayout.LayoutParams layout_description = new RelativeLayout.LayoutParams(imageWidth,imageHeight);
       // mDrawLayout.setLayoutParams(layout_description);

        Bitmap mSignatureBitmapImage = Bitmap.createBitmap(imageWidth,
                imageHeight, Bitmap.Config.ARGB_8888);
        mDrawViewSignature = new DrawingPaint(GalleryImageFullScreen.this/*, lastColor*/);
        mDrawViewSignature.setDrawingCacheEnabled(true);
        mDrawViewSignature.measure(
                View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED),
                View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED));
        mDrawViewSignature.layout(0, 0, mDrawViewSignature.getMeasuredWidth(),
                mDrawViewSignature.getMeasuredHeight());
        mDrawViewSignature.buildDrawingCache(true);

        Canvas canvas = new Canvas(mSignatureBitmapImage);
        Drawable bgDrawable = mDrawLayout.getBackground();
        if (bgDrawable != null) {
            bgDrawable.draw(canvas);
        } else {
            canvas.drawColor(Color.WHITE);
        }
        mDrawLayout.draw(canvas);
        ByteArrayOutputStream bs = new ByteArrayOutputStream();
        mSignatureBitmapImage.compress(Bitmap.CompressFormat.PNG, 50, bs);
    }
    catch (Exception e)
    {
        Logger.d("", "" + e.toString());
    }
    mDrawViewSignature.setColor(getResources().getColor(R.color.black));
    mDrawLayout.addView(mDrawViewSignature);
}

@Override
public void onClick(View v) {

    switch (v.getId())
    {

        case R.id.paint_img_save:
            try {
                Bitmap editedImage = Bitmap.createBitmap(mDrawViewSignature
                        .getDrawingCache());
                editedImage = Bitmap.createScaledBitmap(editedImage, mDrawViewSignature.getWidth(), mDrawViewSignature.getHeight(),
                        true);
                if(editedImage!=null) {
                    final Bitmap finalEditedImage = editedImage;
                    mAlertDialog = Alerts.getInstance().createConfirmationDialog(this, this.getResources().getString(R.string.painting_image_save), new View.OnClickListener() {
                        @Override
                        public void onClick(View v) {
                            /*Bitmap editedImage = Bitmap.createBitmap(mDrawViewSignature
                                    .getDrawingCache());
                            editedImage = Bitmap.createScaledBitmap(editedImage, mDrawViewSignature.getWidth(), mDrawViewSignature.getHeight(),
                                    true);*/
                            //saveImageToInternalStorage(finalEditedImage);
                            storeImage(finalEditedImage);
                            PreferenceForCustomCamera.getInstance().setEditedURL(PreferenceForCustomCamera.getInstance().getImagePathForGalleryFullScreen());
                            callToGalleyActivity();
                            mAlertDialog.dismiss();
                        }
                    });
                    mAlertDialog.show();
                }
            }
            catch (Exception e)
            {
                Logger.d("paint_img_save",""+e.toString());
            }
            break;
        case R.id.paint_img_delete:
            try {
                if (!PreferenceForCustomCamera.getInstance().getImagePathForGalleryFullScreen().equals("") && !PreferenceForCustomCamera.getInstance().getImagePathForGalleryFullScreen().equals("null")) {
                    mAlertDialog = Alerts.getInstance().createConfirmationDialog(this, this.getResources().getString(R.string.painting_image_path_delete), new View.OnClickListener() {
                        @Override
                        public void onClick(View v) {
                          //  DatabaseHelper.getInstance().deleteParticularVideoPath(PreferenceForCustomCamera.getInstance().getImagePathForGalleryFullScreen());
                            CustomGalleryHandler.getmInstance().deleteParticularImages(PreferenceForCustomCamera.getInstance().getImagePathForGalleryFullScreen());
                            CustomGalleryHandler.getmInstance().deleteParticularImageFromInternalStorage(PreferenceForCustomCamera.getInstance().getImagePathForGalleryFullScreen());
                            callToGalleyActivity();
                            mAlertDialog.dismiss();
                        }
                    });
                }
                mAlertDialog.show();
            }
            catch (Exception e)
            {
                Logger.d("paint_img_delete",""+e.toString());
            }
            break;
        case R.id.img_redo:
            mDrawViewSignature.onClickRedo();
            break;
    }
}


private void saveImageToInternalStorage(Bitmap finalBitmap) {
    try {

        File myDir = new File(PreferenceForCustomCamera.getInstance().getImagePathForGalleryFullScreen());
        myDir.mkdirs();
        Logger.d("ListOfPhoto",""+myDir.getAbsolutePath());
        Logger.d("ListOfPhotoRename",""+PreferenceForCustomCamera.getInstance().getImagePathForGalleryFullScreen());
        for(File files: myDir.listFiles())
        {
            Logger.d("ListOfPhoto",""+files.getAbsolutePath());
            Logger.d("ListOfPhotoRename",""+PreferenceForCustomCamera.getInstance().getImagePathForGalleryFullScreen());
        }
        Picasso.with(getApplicationContext()).load(PreferenceForCustomCamera.getInstance().getImagePathForGalleryFullScreen()).skipMemoryCache();
        /*Random generator = new Random();
        int n = 10000;
        n = generator.nextInt(n);
        String fname = "Image-" + "3680" + ".png";
        File file = new File(myDir, fname);
        if (file.exists()) {
            file.delete();
        }*/
        try {
            if(myDir.exists())
            {
                myDir.delete();
            }
            FileOutputStream out = new FileOutputStream(myDir);
            finalBitmap.compress(Bitmap.CompressFormat.PNG, 90, out);
            out.flush();
            out.close();

        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    catch (Exception e)
    {
        Logger.d("saveImageToInternalStorage",""+e.toString());
    }
}

private void storeImage(Bitmap image) {
    File pictureFile = new File(PreferenceForCustomCamera.getInstance().getImagePathForGalleryFullScreen());
    if (pictureFile.exists()) {
        pictureFile.delete();
    }
    //clearImageDiskCache();
    try {
        FileOutputStream fos = new FileOutputStream(pictureFile);
        image.compress(Bitmap.CompressFormat.PNG, 90, fos);
        fos.close();
    } catch (FileNotFoundException e) {
        Logger.d("GalleryImage", "File not found: " + e.getMessage());
    } catch (IOException e) {
        Logger.d("GalleryImage", "Error accessing file: " + e.getMessage());
    }

}


public boolean clearImageDiskCache() {

    File cache = new File(getApplicationContext().getCacheDir(), "picasso-cache");
    if (cache.exists() && cache.isDirectory()) {
        return deleteDir(cache);

    }
    return false;
}
public static boolean deleteDir(File dir) {
    if (dir.isDirectory()) {
        String[] children = dir.list();
        for (int i = 0; i < children.length; i++) {
            boolean success = deleteDir(new File(dir, children[i]));
            if (!success) {
                return false;
            }
        }
    }
    // The directory is now empty so delete it
    return dir.delete();
}

}
like image 501
Vijayadhas Chandrasekaran Avatar asked Aug 29 '16 06:08

Vijayadhas Chandrasekaran


2 Answers

For drawing only on bitmap, use SRC_IN PorterDuffXfermode.

mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));

this will write only on the area where you have already written .

like image 161
Mr.Rao Avatar answered Nov 07 '22 03:11

Mr.Rao


The View you create and the bitmap Size may differ Override the onMesaure and set the width & height of the view, this will create a canvas of the bitmap size so that it wont get stretched , if the bitmap is size is greater than screen Dimensions you will be able to draw outside the screen too. If the Canvas is the size of the bitmap it should solve both your problems

like image 2
surya Avatar answered Nov 07 '22 05:11

surya