- I have created a custom imageview class. Here I use the function
public void setNewImage(Bitmap alteredBitmap, Bitmap bmp, float paintSize, int paintColor)
in which alteredBitmap is a bitmap that does not contain an image, bmp is a bitmap that contains an image to initialize Paint and Canvas. Then i will use void onTouch() to draw on the image.
Problem: when I changed the mode to eraser mode using the
void isDrawing(boolean b, int color, float size)function, it erased both the path and the bitmap drawn below.Desired result: I only want to delete the path, not the bitmap drawn below.
Note: in this class I use
void setImageBitmap(alteredBitmap);to assign images rather than using functions@Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); }
This is my class:
public class DrawableImageView2 extends androidx.appcompat.widget.AppCompatImageView implements View.OnTouchListener, MultiTouchListener.OnMultiTouchListener {
public DrawableImageView2(Context context, AttributeSet attrs,
int defStyleAttr) {
super(context, attrs, defStyleAttr);
setOnTouchListener(this);
}
@Override
public boolean onTouch(View v, MotionEvent event) {
int action = event.getAction();
switch (action) {
case MotionEvent.ACTION_DOWN:
downx = getPointerCoords(event)[0];//event.getX();
downy = getPointerCoords(event)[1];//event.getY();
if (isDrawing) {
path.reset();
path.moveTo(downx, downy);
} else {
path.reset();
path.moveTo(downx, downy);
}
break;
case MotionEvent.ACTION_MOVE:
upx = getPointerCoords(event)[0];//event.getX();
upy = getPointerCoords(event)[1];//event.getY();
path.lineTo(upx, upy);
canvas.drawPath(path, paint);
invalidate();
downx = upx;
downy = upy;
break;
case MotionEvent.ACTION_UP:
upx = getPointerCoords(event)[0];//event.getX();
upy = getPointerCoords(event)[1];//event.getY();
if (isDrawing) {
undoList.add(new MapEntry<>(paint, path));
canvas.drawPath(path, paint);
path = new Path();
} else {
path.lineTo(upx, upy);
canvas.drawPath(path, paint);
}
Log.d(TAG, "onTouch: ACTION_UP: upx = " + upx + " upy = " + upy);
invalidate();
break;
case MotionEvent.ACTION_CANCEL:
break;
default:
break;
}
return true;
}
public void setNewImage(Bitmap alteredBitmap, Bitmap bmp, float paintSize, int paintColor) {
canvas = new Canvas(alteredBitmap);
paint = new Paint();
paint.setColor(paintColor);
paint.setStrokeWidth(paintSize);
paint.setAntiAlias(true);
paint.setDither(true);
paint.setStyle(Paint.Style.STROKE);
paint.setStrokeJoin(Paint.Join.ROUND);
paint.setStrokeCap(Paint.Cap.ROUND);
paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_OVER));
matrix = new Matrix();
originalBitmap = bmp;
canvas.drawBitmap(bmp, matrix, paint);
setImageBitmap(alteredBitmap);
Rect rect = getDrawable().getBounds();
Log.d(TAG, "drawBorder: rect: " + rect);
}
final float[] getPointerCoords(MotionEvent e) {
final int index = e.getActionIndex();
final float[] coords = new float[]{e.getX(index), e.getY(index)};
Matrix matrix = new Matrix();
getImageMatrix().invert(matrix);
matrix.postTranslate(getScrollX(), getScrollY());
matrix.mapPoints(coords);
return coords;
}
public void isDrawing(boolean b, int color, float size) {
isDrawing = b;
if (b) {
paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_OVER)); // Chuyển về chế độ vẽ bằng cách xóa Xfermode
paint.setColor(color); // Thiết lập màu sắc cho chế độ vẽ
paint.setStrokeWidth(size);
} else {
paint.setMaskFilter(null); // Xóa MaskFilter
paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR)); // Chuyển sang chế độ xóa
paint.setAntiAlias(true);
}
}
public void setOptionPaint(int mValue, float mSize) {
paint = new Paint();
paint.setColor(mValue);
paint.setStrokeWidth(mSize);
paint.setAntiAlias(true);
paint.setDither(true);
paint.setStyle(Paint.Style.STROKE);
paint.setStrokeJoin(Paint.Join.ROUND);
paint.setStrokeCap(Paint.Cap.ROUND);
paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DARKEN));
}
}