1

I am having an Image and I want to write on Image which can be rotated, resized and re-positioned. I am new to Canvas. I don't understand ,How to achieve it ?enter image description here

Hritik Gupta
  • 611
  • 5
  • 20
  • this is not one of the easiest tasks, I would recommend to find yourself a library that already does this. If you are determined to do this yourself, take a look at `SurfaceView`, it might be of great help. – Daniel Sep 10 '19 at 15:05
  • see `MatrixGestureDetector` from [here](https://stackoverflow.com/a/21657145/2252830) – pskink Sep 10 '19 at 15:11

1 Answers1

0

Hi i write this code for one of my project you can use it for rotated, resized and re-positioned and for add text you need to change it a little :

public class ScreenView extends View implements RotationGestureDetector.OnRotationGestureListener, ScaleGestureDetector.OnScaleGestureListener {
    private Context context = null;
    private Bitmap bitmap = null;
    private Bitmap bitmapLocked = null;
    private int baseColor = Color.parseColor("#ffffff");
    public int width;
    public int height;

    public float touchStartX;
    public float touchStartY;
    public float touchX;
    public float touchY;

    public boolean touchDown = false;

    private Products product;

    ArrayList<Products> products = new ArrayList<>();
    private float newAngle = 0;
    private float newScale = 0;
    private float scaleFactorSum = 0;
    private float startScale = 0;
    private RotationGestureDetector rotationDetector;
    private ScaleGestureDetector scaleDetector;
    private boolean isRotating = false;
    private boolean isScaling = false;
    private Matrix m;
    private float startX;
    private float startY;
    private float startAngle;
    private boolean isLocked;
    private Paint alphaPaint = new Paint();

    public ScreenView(Context context) {
        super(context);
        this.setup(context);
    }

    public ScreenView(Context context, AttributeSet attrs) {
        super(context, attrs);
        this.setup(context);
    }

    private void setup(Context context) {
        this.context = context;

        rotationDetector = new RotationGestureDetector(this);
        scaleDetector = new ScaleGestureDetector(context, this);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);

        canvas.drawColor(Color.parseColor("#ffffff"));
        if (bitmap != null) {
            canvas.drawBitmap(bitmap, 0, 0, null);
        }


        for (Products item : products) {

            if (getSelectedProduct() != null && !getSelectedProduct().equals(item))
                canvas.drawBitmap(item.getBitmap(), item.getMatrix(), null);
            else if (!touchDown) {
                canvas.drawBitmap(item.getBitmap(), item.getMatrix(), null);

            }
        }
        if (touchDown && getSelectedProduct() != null) {

            canvas.drawBitmap(getSelectedProduct().getBitmap(), getSelectedProduct().getMatrix(), null);
        }

    }

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

        width = w;
        height = h;

        invalidate();

    }

    public void setAvatarBitmap(Bitmap bitmap, int width, int height) {

        this.bitmap = Bitmap.createScaledBitmap(bitmap, width, height, false);

        invalidate();
    }

    public void addProduct(Products item) {

        products.add(item);

        invalidate();
    }
    public void addAllProduct(ArrayList<Products> item) {

        products = item;

        invalidate();
    }

    public int getLastIdOfProduct() {

        boolean position1 = false;
        boolean position2 = false;
        boolean position3 = false;
        boolean position4 = false;
        for (int i = 0; i < products.size(); i++) {
            if (products.get(i).getPosition() == 1) {
                position1 = true;
            }
            if (products.get(i).getPosition() == 2) {
                position2 = true;
            }
            if (products.get(i).getPosition() == 3) {
                position3 = true;
            }
            if (products.get(i).getPosition() == 4) {
                position4 = true;
            }
        }
        if (!position1 && products.size() == 0 )
            return 1;
        if (!position2)
            return 2;
        if (!position3)
            return 3;
        if (!position4)
            return 4;

        return 1;
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        if (getSelectedProduct() == null) {
            return true;
        }
        scaleDetector.onTouchEvent(event);
        rotationDetector.onTouchEvent(event);

        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:

                if (!this.touchDown) {
                    touchStartX = event.getX();
                    touchStartY = event.getY();

                    startX = getSelectedProduct().x;
                    startY = getSelectedProduct().y;
                    startAngle = getSelectedProduct().angle;
                    touchDown = true;


                }
                break;
            case MotionEvent.ACTION_MOVE:

                touchX = event.getX();
                touchY = event.getY();
                if (!isScaling && !isRotating && getSelectedProduct().isCanMove()) {
                    getSelectedProduct().setXY(startX + (touchX - touchStartX), startY + (touchY - touchStartY));

                }

                this.invalidate();

                break;
            case MotionEvent.ACTION_UP:

                if (!isScaling && !isRotating && getSelectedProduct().isCanMove()) {
                    getSelectedProduct().setXY(startX + (touchX - touchStartX), startY + (touchY - touchStartY));
                }
                touchX = 0;
                touchY = 0;
                touchStartX = 0;
                touchStartY = 0;
                this.touchDown = false;
                this.invalidate();

                break;
            default:
                break;
        }


        ViewParent mParent = getParent();
        if (mParent != null) {
            mParent.requestDisallowInterceptTouchEvent(true);
        }
        return true;

    }

    public Products getSelectedProduct() {

        return product;
    }

    public void setProduct(Products product) {
        this.product = product;
    }

    public void setSelectedProduct(int id) {

        for (int i = 0; i <= products.size() - 1; i++) {
            if (products.get(i).getId() == id) {
                this.product = products.get(i);
                break;

            }

        }

    }

    public ArrayList<Products> getAllProducts() {
        return products;
    }

    @Override
    public void OnRotation(RotationGestureDetector rotationDetector) {
        if (!getSelectedProduct().isCanRotate()) {
            return;
        }
        isRotating = true;
        newAngle = -rotationDetector.getAngle();

        getSelectedProduct().setAngle(startAngle + newAngle);
    }

    @Override
    public void onRotationEnded(RotationGestureDetector rotationDetector) {

        if (!isRotating || !getSelectedProduct().isCanRotate()) {
            return;
        }

        getSelectedProduct().setAngle(startAngle + newAngle);

        touchX = 0;
        touchY = 0;
        touchStartX = 0;
        touchStartY = 0;
        isRotating = false;
        this.newAngle = 0;

    }

    @Override
    public boolean onScale(ScaleGestureDetector detector) {

        if (!getSelectedProduct().isCanScale()) {
            return false;
        }

        newScale -= (1 - detector.getScaleFactor()) * 2;

        getSelectedProduct().setScale(startScale + newScale);
        return true;
    }

    @Override
    public boolean onScaleBegin(ScaleGestureDetector detector) {
        if (getSelectedProduct().isCanScale()) {
            isScaling = true;
            startScale = getSelectedProduct().scale;
        }
        return true;
    }

    @Override
    public void onScaleEnd(ScaleGestureDetector detector) {

        touchX = 0;
        touchY = 0;
        touchStartX = 0;
        touchStartY = 0;
        newScale = 0;

        isScaling = false;

    }

    public Bitmap getBitmap() {
        try {
            this.setDrawingCacheEnabled(false);
            this.setDrawingCacheEnabled(true);

            return Bitmap.createBitmap(this.getDrawingCache());
        } catch (Exception e) {
            return null;
        }
    }

    public void removeProductFromList(Products item) {
        if (item != null) {
            products.remove(item);
            product = null;
            invalidate();
        }
    }

    public void removeAllProduct() {
        products.clear();
        product = null;
        invalidate();

    }

    public boolean isLocked() {
        return isLocked;
    }

    public void setLocked(boolean locked) {
        isLocked = locked;
    }

}




public class RotationGestureDetector {
    private static final int INVALID_POINTER_ID = -1;
    private float fX, fY, sX, sY;
    private int ptrID1, ptrID2;
    private float mAngle;

    private OnRotationGestureListener mListener;

    public float getAngle() {
        return mAngle;
    }

    public RotationGestureDetector(OnRotationGestureListener listener){
        mListener = listener;
        ptrID1 = INVALID_POINTER_ID;
        ptrID2 = INVALID_POINTER_ID;
    }

    public boolean onTouchEvent(MotionEvent event){
        switch (event.getActionMasked()) {
            case MotionEvent.ACTION_DOWN:
                ptrID1 = event.getPointerId(event.getActionIndex());
                break;
            case MotionEvent.ACTION_POINTER_DOWN:
                ptrID2 = event.getPointerId(event.getActionIndex());
                sX = event.getX(event.findPointerIndex(ptrID1));
                sY = event.getY(event.findPointerIndex(ptrID1));
                fX = event.getX(event.findPointerIndex(ptrID2));
                fY = event.getY(event.findPointerIndex(ptrID2));
                break;
            case MotionEvent.ACTION_MOVE:
                if(ptrID1 != INVALID_POINTER_ID && ptrID2 != INVALID_POINTER_ID){
                    float nfX, nfY, nsX, nsY;
                    nsX = event.getX(event.findPointerIndex(ptrID1));
                    nsY = event.getY(event.findPointerIndex(ptrID1));
                    nfX = event.getX(event.findPointerIndex(ptrID2));
                    nfY = event.getY(event.findPointerIndex(ptrID2));

                    mAngle = angleBetweenLines(fX, fY, sX, sY, nfX, nfY, nsX, nsY);

                    if (mListener != null) {
                        mListener.OnRotation(this);
                    }
                }
                break;
            case MotionEvent.ACTION_UP:
                ptrID1 = INVALID_POINTER_ID;
                break;
            case MotionEvent.ACTION_POINTER_UP:
                ptrID2 = INVALID_POINTER_ID;
                break;
            case MotionEvent.ACTION_CANCEL:
                ptrID1 = INVALID_POINTER_ID;
                ptrID2 = INVALID_POINTER_ID;
                break;
        }

        if(ptrID1 == INVALID_POINTER_ID && ptrID2 == INVALID_POINTER_ID){
            mListener.onRotationEnded(this);
        }

        return true;
    }

    private float angleBetweenLines (float fX, float fY, float sX, float sY, float nfX, float nfY, float nsX, float nsY)
    {
        float angle1 = (float) Math.atan2( (fY - sY), (fX - sX) );
        float angle2 = (float) Math.atan2( (nfY - nsY), (nfX - nsX) );

        float angle = ((float) Math.toDegrees(angle1 - angle2)) % 360;
        if (angle < -180.f) angle += 360.0f;
        if (angle > 180.f) angle -= 360.0f;
        return angle;
    }

    public static interface OnRotationGestureListener {
        public void OnRotation(RotationGestureDetector rotationDetector);
        public void onRotationEnded(RotationGestureDetector rotationDetector);
    }
}

for use the code :

screenView.addProduct(new Products(screenView.getLastIdOfProduct(), item.getHash(), x, y, resource, width, height, scale, position, canMove, canScale, canRotate));

the code use for this page