使用PorterDuff模式擦除位图部件

我尝试通过使用Porter-Duff Xfermodes来擦除Android应用程序中的位图部分。

我有一个蓝色的位图叠加的绿色背景。 当我触摸屏幕时,应该创build覆盖位图中的“洞”,使得绿色背景可见。 而不是一个洞,我现在的代码产生一个黑点。

以下是我的代码。 任何想法,我在做什么错在这里?

/** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN); setContentView(new DrawView(this)); } public class DrawView extends View implements OnTouchListener { private int x = 0; private int y = 0; Bitmap bitmap; Canvas bitmapCanvas; 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.GREEN); // Set bitmap bitmap = Bitmap.createBitmap(320, 480, Bitmap.Config.RGB_565); bitmapCanvas = new Canvas(); bitmapCanvas.setBitmap(bitmap); bitmapCanvas.drawColor(Color.BLUE); // Set eraser paint properties eraserPaint.setAlpha(0); eraserPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_IN)); eraserPaint.setAntiAlias(true); } @Override public void onDraw(Canvas canvas) { bitmapCanvas.drawColor(Color.BLUE); bitmapCanvas.drawCircle(x, y, 10, eraserPaint); canvas.drawBitmap(bitmap, 0, 0, paint); } public boolean onTouch(View view, MotionEvent event) { x = (int) event.getX(); y = (int) event.getY(); invalidate(); return true; } } 

首先想到的是,我不确定在擦除画笔对象上设置alpha为0是一个好主意。 这可能会使整个事情无效。

另外,如果你正在处理alpha,你应该总是使用Bitmap.Config.ARGB_8888。

如果你对PorterDuff的东西有麻烦,我会build议简化你的方法,只做(临时)。 这将帮助你缩小不工作的部分。 评论一切与触摸和查看更新。

然后你可以选出哪部分工作不正常。 像这样设置你的构造函数:

 DrawView() { /* Create the background green bitmap */ ... /* Create foreground transparent bitmap */ ... /* Draw a blue circle on the foreground bitmap */ ... /* Apply the foreground to the background bitmap using a PorterDuff method */ ... } onDraw() { /* Simply draw the background bitmap */ ... } 

如果你这样设置,你应该能够告诉你的PD方法如何影响绿色位图,并相应地改变一些事情。

这是工作代码…可以帮助别人

 public class ImageDemo extends Activity { @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(new Panel(this)); } class Panel extends View { private Bitmap mBitmap; private Canvas mCanvas; private Path mPath; private Paint mPaint; Bitmap bitmap; Canvas pcanvas; int x = 0; int y =0; int r =0; public Panel(Context context) { super(context); Log.v("Panel", ">>>>>>"); setFocusable(true); setBackgroundColor(Color.GREEN); // setting paint mPaint = new Paint(); mPaint.setAlpha(0); mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_IN)); mPaint.setAntiAlias(true); // getting image from resources Resources r = this.getContext().getResources(); Bitmap bm = BitmapFactory.decodeResource(getResources(), R.drawable.mickey); // converting image bitmap into mutable bitmap bitmap = bm.createBitmap(295, 260, Config.ARGB_8888); pcanvas = new Canvas(); pcanvas.setBitmap(bitmap); // drawXY will result on that Bitmap pcanvas.drawBitmap(bm, 0, 0, null); } @Override protected void onDraw(Canvas canvas) { // draw a circle that is erasing bitmap pcanvas.drawCircle(x, y, r, mPaint); canvas.drawBitmap(bitmap, 0, 0,null); super.onDraw(canvas); } @Override public boolean onTouchEvent(MotionEvent event) { // set parameter to draw circle on touch event x = (int) event.getX(); y = (int) event.getY(); r =20; // At last invalidate canvas invalidate(); return true; } } } 

这是您的解决scheme的另一个进步… 请参阅演示示例

 public class MainActivity extends Activity { Bitmap bp; Canvas bitmapCanvas; DrawView drawImg; LinearLayout ln1; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); ln1 = (LinearLayout) findViewById(R.id.ln1); drawImg = new DrawView(this); ln1.addView(drawImg); } public class DrawView 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; } } } 

阅读更多