如何在不绘制透明部分的情况下用手指在View中绘制?
How to draw with finger in View without drawing in transparent parts?
假设我有 500 x 500 ImageView,一半 ImageView 是红色的,第二部分是透明的。
我只想在 ImageVIew 的非透明部分用手指绘制,所以如果我在透明部分绘制,它将不可见,就像这个图像。
可能吗 ?
我试过了,但这段代码不正确。
public class DrawingView extends ImageView {
private boolean isTransparent;
private float mX, mY;
private static final float TOUCH_TOLERANCE = 4;
private Bitmap mBitmap;
private Canvas mCanvas;
private Path mPath;
private Paint mBitmapPaint;
Context mContext;
private Path circlePath;
public DrawingView(Context c) {
super(c);
mContext = c;
mPath = new Path();
mBitmapPaint = new Paint(Paint.DITHER_FLAG);
circlePath = new Path();
}
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
mBitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_4444);
mCanvas = new Canvas(mBitmap);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
if (mBitmap != null && canvas != null && !isTransparent) {
canvas.drawBitmap(mBitmap, 0, 0, mBitmapPaint);
canvas.drawPath(mPath, mPaint);
}
}
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) {
if(mBitmap.getPixel((int)x, (int)y) == Color.TRANSPARENT || mBitmap.getPixel((int)mY, (int)mY) == Color.TRANSPARENT) {
isTransparent = true;
} else {
isTransparent = false;
}
mPath.quadTo(mX, mY, (x + mX) / 2, (y + mY) / 2);
mX = x;
mY = y;
circlePath.reset();
circlePath.addCircle(mX, mY, 30, Path.Direction.CW);
}
}
private void touch_up() {
mPath.lineTo(mX, mY);
circlePath.reset();
mCanvas.drawPath(mPath, mPaint);
mPath.reset();
}
@Override
public boolean onTouchEvent(MotionEvent event) {
float x = event.getX();
float y = event.getY();
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
touch_start(x, y);
invalidate();
break;
case MotionEvent.ACTION_MOVE:
touch_move(x, y);
invalidate();
break;
case MotionEvent.ACTION_UP:
touch_up();
invalidate();
break;
}
return true;
}
}
我不知道 mPaint
在哪里初始化,但由于 mPaint
用于绘制手指轨迹,因此将此行放入应该可以完成您想要的操作:
mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_ATOP));
请参阅 this image 了解说明。
假设我有 500 x 500 ImageView,一半 ImageView 是红色的,第二部分是透明的。
我只想在 ImageVIew 的非透明部分用手指绘制,所以如果我在透明部分绘制,它将不可见,就像这个图像。
可能吗 ?
我试过了,但这段代码不正确。
public class DrawingView extends ImageView {
private boolean isTransparent;
private float mX, mY;
private static final float TOUCH_TOLERANCE = 4;
private Bitmap mBitmap;
private Canvas mCanvas;
private Path mPath;
private Paint mBitmapPaint;
Context mContext;
private Path circlePath;
public DrawingView(Context c) {
super(c);
mContext = c;
mPath = new Path();
mBitmapPaint = new Paint(Paint.DITHER_FLAG);
circlePath = new Path();
}
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
mBitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_4444);
mCanvas = new Canvas(mBitmap);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
if (mBitmap != null && canvas != null && !isTransparent) {
canvas.drawBitmap(mBitmap, 0, 0, mBitmapPaint);
canvas.drawPath(mPath, mPaint);
}
}
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) {
if(mBitmap.getPixel((int)x, (int)y) == Color.TRANSPARENT || mBitmap.getPixel((int)mY, (int)mY) == Color.TRANSPARENT) {
isTransparent = true;
} else {
isTransparent = false;
}
mPath.quadTo(mX, mY, (x + mX) / 2, (y + mY) / 2);
mX = x;
mY = y;
circlePath.reset();
circlePath.addCircle(mX, mY, 30, Path.Direction.CW);
}
}
private void touch_up() {
mPath.lineTo(mX, mY);
circlePath.reset();
mCanvas.drawPath(mPath, mPaint);
mPath.reset();
}
@Override
public boolean onTouchEvent(MotionEvent event) {
float x = event.getX();
float y = event.getY();
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
touch_start(x, y);
invalidate();
break;
case MotionEvent.ACTION_MOVE:
touch_move(x, y);
invalidate();
break;
case MotionEvent.ACTION_UP:
touch_up();
invalidate();
break;
}
return true;
}
}
我不知道 mPaint
在哪里初始化,但由于 mPaint
用于绘制手指轨迹,因此将此行放入应该可以完成您想要的操作:
mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_ATOP));
请参阅 this image 了解说明。