MrZaiko/Polysmee

View on GitHub
app/src/main/java/io/github/polysmee/photo/editing/DrawableImageView.java

Summary

Maintainability
A
0 mins
Test Coverage
F
54%
package io.github.polysmee.photo.editing;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Path;
import android.util.AttributeSet;
import android.view.MotionEvent;

import io.github.polysmee.R;


/**
 * Class to implement the custom image view to be used when sharing pictures
 */
public class DrawableImageView extends androidx.appcompat.widget.AppCompatImageView {
    private final Paint paint;
    private final Path path;

    private Canvas alteredCanvas;
    private Bitmap alteredBitmap;

    private int currentColorId;
    private float currentStrokeWidth;

    private float previousX, previousY;

    private final static int DEFAULT_STROKE_WIDTH = 5;

    public DrawableImageView(Context context, AttributeSet attrs) {
        super(context, attrs);

        paint = new Paint();
        paint.setColor(getResources().getColor(R.color.primaryColor));
        currentColorId = R.color.primaryColor;
        paint.setAntiAlias(true);
        paint.setStyle(Paint.Style.STROKE);
        paint.setStrokeJoin(Paint.Join.ROUND);
        paint.setStrokeWidth(DEFAULT_STROKE_WIDTH);
        currentStrokeWidth = DEFAULT_STROKE_WIDTH;

        path = new Path();
    }

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

        if (alteredBitmap.getWidth() >= alteredBitmap.getHeight()) {
            float aspectRatio = alteredBitmap.getWidth() / (float) alteredBitmap.getHeight();
            int height = Math.round(w / aspectRatio);
            alteredBitmap = Bitmap.createScaledBitmap(
                    alteredBitmap, w, height, false);
        } else {
            float aspectRatio = alteredBitmap.getHeight() / (float) alteredBitmap.getWidth();
            int width = Math.round(h / aspectRatio);
            alteredBitmap = Bitmap.createScaledBitmap(
                    alteredBitmap, width, h, false);
        }


        alteredCanvas = new Canvas(alteredBitmap);
    }

    @Override
    public void setImageBitmap(Bitmap bitmap) {
        super.setImageBitmap(bitmap);

        int width = bitmap.getWidth();
        int height = bitmap.getHeight();

        //keep the previous size
        if (alteredBitmap != null) {
            width = alteredBitmap.getWidth();
            height = alteredBitmap.getHeight();
        }

        alteredBitmap = Bitmap.createBitmap(bitmap.getWidth(), bitmap.getHeight(), bitmap.getConfig());
        alteredCanvas = new Canvas(alteredBitmap);
        alteredCanvas.drawBitmap(bitmap, 0, 0, null);

        onSizeChanged(width, height, bitmap.getWidth(), bitmap.getHeight());
    }

    public void setStrokeWidth(float strokeWidth) {
        currentStrokeWidth = strokeWidth;
        paint.setStrokeWidth(strokeWidth);
    }

    /**
     *
     * @return the current stroke width
     */
    public float getCurrentStrokeWidth() {
        return currentStrokeWidth;
    }

    public void setColor(int colorId) {
        currentColorId = colorId;
        paint.setColor(colorId);
    }

    /**
     *
     * @return the current color id
     */
    public int getCurrentColorId() {
        return currentColorId;
    }

    private void touchStart(float x, float y) {
        path.reset();
        path.moveTo(x, y);
        previousX = x;
        previousY = y;
    }

    private void touchMove(float x, float y) {
        float dx = Math.abs(x - previousX);
        float dy = Math.abs(y - previousX);
        if (dx >= DEFAULT_STROKE_WIDTH || dy >= DEFAULT_STROKE_WIDTH) {
            path.quadTo(previousX, previousY, (x + previousX) / 2, (y + previousY) / 2);
            previousX = x;
            previousY = y;
        }
    }

    private void touchUp() {
        path.lineTo(previousX, previousY);
        // commit the path to our offscreen
        alteredCanvas.drawPath(path, paint);
        // kill this so we don't double draw
        path.reset();
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        float x = event.getX();
        float y = event.getY();
        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                touchStart(x, y);
                invalidate();
                break;
            case MotionEvent.ACTION_UP:
                touchUp();
                invalidate();
                break;
            case MotionEvent.ACTION_MOVE:
                touchMove(x, y);
                invalidate();
                break;
        }
        return true;
    }

    protected void onDraw(Canvas canvas) {
        canvas.drawBitmap(alteredBitmap, 0, 0, null);
        canvas.drawPath(path, paint);
    }

    public Bitmap getAlteredPicture() {
        return alteredBitmap;
    }
}