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 ?
Asked
Active
Viewed 41 times
1

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 Answers
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));