setXfermode
设置两张图片相交时的模式 我们知道 在正常的情况下,在已有的图像上绘图将会在其上面添加一层新的形状。 如果新的Paint是完全不透明的,那么它将完全遮挡住下面的Paint; 而setXfermode就可以来解决这个问题 一般来说 用法是这样的
Canvas canvas = new Canvas(bitmap1);paint.setXfermode(new PorterDuffXfermode(Mode.SRC_IN));canvas.drawBitmap(mask, 0f, 0f, paint);
就是在图片bitmap1上面绘制图片mask时 处理两者相交时候显示的问题 canvas原有的图片 可以理解为背景 就是dst 新画上去的图片 可以理解为前景 就是src Mode的值 如下图
PorterDuff.Mode.CLEAR 清除画布上图像
PorterDuff.Mode.SRC 显示上层图像 PorterDuff.Mode.DST 显示下层图像 PorterDuff.Mode.SRC_OVER上下层图像都显示,上层居上显示 PorterDuff.Mode.DST_OVER 上下层都显示,下层居上显示 PorterDuff.Mode.SRC_IN 取两层图像交集部门,只显示上层图像 PorterDuff.Mode.DST_IN 取两层图像交集部门,只显示下层图像 PorterDuff.Mode.SRC_OUT 取上层图像非交集部门 PorterDuff.Mode.DST_OUT 取下层图像非交集部门 PorterDuff.Mode.SRC_ATOP 取下层图像非交集部门与上层图像交集部门 PorterDuff.Mode.DST_ATOP 取上层图像非交集部门与下层图像交集部门 PorterDuff.Mode.XOR 取两层图像的非交集部门画图示例(画圆角矩形轨迹 常用语市面上流行的poker倒计时):
package com.k.gameview;import android.content.Context;import android.graphics.Canvas;import android.graphics.Color;import android.graphics.Paint;import android.graphics.PorterDuff.Mode;import android.graphics.PorterDuffXfermode;import android.graphics.Rect;import android.graphics.RectF;import android.graphics.Region;import android.view.KeyEvent;import android.view.MotionEvent;import android.view.View; public class GameView1 extends View implements Runnable { /* 声明Paint对象 */ private Paint mPaint = null; public GameView1(Context context) { super(context); /* 构建对象 */ mPaint = new Paint(); /* 开启线程 */ new Thread(this).start(); } float arc; public void onDraw(Canvas canvas) { super.onDraw(canvas); if(arc>360) arc=0; /* 设置画布的颜色 */ canvas.drawColor(Color.BLACK); /* 设置取消锯齿效果 */ mPaint.setAntiAlias(true); mPaint.setAlpha(255); if(arc>200){ mPaint.setColor(Color.YELLOW); }else{ mPaint.setColor(Color.GREEN); } mPaint.setStyle(Paint.Style.STROKE); mPaint.setStrokeWidth(5); RectF rf = new RectF(10, 10, 90, 140); canvas.drawRoundRect(rf, 10, 10, mPaint); mPaint.setXfermode(new PorterDuffXfermode(Mode.SRC_IN)); mPaint.setAlpha(0); mPaint.setStyle(Paint.Style.FILL); canvas.drawArc(new RectF(-100, -75, 200, 225), 240, arc, true, mPaint); arc+=2.5; } // 触笔事件 public boolean onTouchEvent(MotionEvent event) { return true; } // 按键按下事件 public boolean onKeyDown(int keyCode, KeyEvent event) { return true; } // 按键弹起事件 public boolean onKeyUp(int keyCode, KeyEvent event) { return false; } public boolean onKeyMultiple(int keyCode, int repeatCount, KeyEvent event) { return true; } public void run() { while (!Thread.currentThread().isInterrupted()) { try { Thread.sleep(100); } catch (InterruptedException e) { Thread.currentThread().interrupt(); } // 使用postInvalidate可以直接在线程中更新界面 postInvalidate(); } }}
注注:部分内容来源网络