【问题标题】:How to erase part of a Bitmap using PorterDuff Xfermodes and Alpha Mask?如何使用 PorterDuff Xfermodes 和 Alpha Mask 擦除位图的一部分?
【发布时间】:2026-01-10 11:30:01
【问题描述】:

我有一个 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);

【问题讨论】:

    标签: android android-canvas porter-duff xfermode


    【解决方案1】:
    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>
    

    希望对你有帮助

    【讨论】:

      最近更新 更多