android - 如何使用 PorterDuff Xfermodes 和 Alpha Mask 删除位图的一部分?

标签 android android-canvas porter-duff xfermode

我有一个 alpha 蒙版,我想将这个蒙版用作橡皮,当用户在屏幕上触摸时,位图的那部分应该作为 alpha 蒙版的形状被删除。我试过了,但它总是将整个位图作为掩码而不是 alpha 部分。稍后,用户将保存位图,以便那些删除的部分应该是透明的。

这是我使用的代码:

    paintMask.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));

    Canvas canvas = new Canvas(bitmapOriginal);
    int sc = canvas.saveLayer(0, 0, width, height, null, Canvas.ALL_SAVE_FLAG);
    canvas.drawBitmap(bitmapOriginal, 0, 0, null);
    canvas.drawBitmap(bitmapMask, 0, 0, paintMask);
    canvas.restoreToCount(sc);

最佳答案

public class DrawingView extends View implements View.OnTouchListener {

    private int x = 0;
    private int y = 0;

    Bitmap bitmap;
    Path circlePath;
    Paint circlePaint;

    private final Paint paint = new Paint();
    private final Paint eraserPaint = new Paint();


    public DrawView(Context context){
        super(context);
        setFocusable(true);
        setFocusableInTouchMode(true);
        this.setOnTouchListener(this);

        // Set background
        this.setBackgroundColor(Color.CYAN);
        bp = BitmapFactory.decodeResource(getResources(), R.drawable.bg);

        // Set bitmap
        bitmap = Bitmap.createBitmap(320, 480, Bitmap.Config.ARGB_8888);
        bitmapCanvas = new Canvas();
        bitmapCanvas.setBitmap(bitmap);
        bitmapCanvas.drawColor(Color.TRANSPARENT);
        bitmapCanvas.drawBitmap(bp, 0, 0, null);

        circlePath = new Path();
        circlePaint = new Paint();
        circlePaint.setAntiAlias(true);
        circlePaint.setColor(Color.BLUE);
        circlePaint.setStyle(Paint.Style.STROKE);
        circlePaint.setStrokeJoin(Paint.Join.MITER);
        circlePaint.setStrokeWidth(4f);

        // Set eraser paint properties
        eraserPaint.setAlpha(0);
        eraserPaint.setStrokeJoin(Paint.Join.ROUND);
        eraserPaint.setStrokeCap(Paint.Cap.ROUND);
        eraserPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));
        eraserPaint.setAntiAlias(true);

    }

    @Override
    public void onDraw(Canvas canvas) {

        canvas.drawBitmap(bitmap, 0, 0, paint);
        bitmapCanvas.drawCircle(x, y, 30, eraserPaint);

        canvas.drawPath(circlePath, circlePaint);
    }

    public boolean onTouch(View view, MotionEvent event) {
        x = (int) event.getX();
        y = (int) event.getY();

        bitmapCanvas.drawCircle(x, y, 30, eraserPaint);

        circlePath.reset();
        circlePath.addCircle(x, y, 30, Path.Direction.CW);

        int ac=event.getAction();
        switch(ac){
            case MotionEvent.ACTION_UP:
                Toast.makeText(MainActivity.this, String.valueOf(x), Toast.LENGTH_SHORT).show();
                circlePath.reset();
                break;
        }
        invalidate();
        return true;
    }
}

在你的布局文件中......

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:background="#00ff00"
tools:context=".MainActivity">
<DrawingView
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:id="@+id/ln1"
    android:orientation="vertical"
    /></LinearLayout>

希望对您有所帮助

关于android - 如何使用 PorterDuff Xfermodes 和 Alpha Mask 删除位图的一部分?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53775152/

相关文章:

java - 处理从可检查菜单中选择的项目

android - 有没有办法获取 OkHttp 客户端上的当前请求数?

android - Android中的Indefinite ProgressDialog崩溃应用程序

java - 从canvas java创建位图

Android在centerCropped图片中创建一个圆孔

android - 如何从 Android 中的另一个应用程序关闭/发送到后台 Activity ?

android - 在 Canvas 上绘制图片时应用不透明度(或绘画)

java - 在 Canvas 和多个绘画对象上绘图

android - DrawableCompat.setTint(drawable, color) vs Drawable.setColorFilter(color, mode)

android - 在填充的 android Canvas 上绘制一个透明圆圈