1、概述

在android图形渲染中 会使用到图像混合模式

<span style="font-size:18px;">setXfermode(Xfermode xfermode)</span>

Xfermode有三个子类

AvoidXfermode, PixelXorXfermode,这俩个均已经被淘汰
只剩 【PorterDuffXfermode】,这个模式是由俩个大牛Tomas Proter和Tom Duff名字来命名的,PorterDuffXfermode模式能为android图形渲染做啥呢,先来张经典图片

咋看有点晕,先解释一下

1.PorterDuff.Mode.CLEAR :所绘制不会提交到画布上。
2.PorterDuff.Mode.SRC : 显示上层绘制图片
3.PorterDuff.Mode.DST : 显示下层绘制图片
4.PorterDuff.Mode.SRC_OVER : 正常绘制显示,上下层绘制叠盖。
5.PorterDuff.Mode.DST_OVER : 上下层都显示。下层居上显示。
6.PorterDuff.Mode.SRC_IN : 取两层绘制交集。显示上层。
7.PorterDuff.Mode.DST_IN :取两层绘制交集。显示下层。
8.PorterDuff.Mode.SRC_OUT :取上层绘制非交集部分。
9.PorterDuff.Mode.DST_OUT : 取下层绘制非交集部分。
10.PorterDuff.Mode.SRC_ATOP :取下层非交集部分与上层交集部分
11.PorterDuff.Mode.DST_ATOP : 取上层非交集部分与下层交集部分
12.PorterDuff.Mode.XOR : 异或:去除两图层交集部分
13.PorterDuff.Mode.DARKEN :取两图层全部区域,交集部分颜色加深
14.PorterDuff.Mode.LIGHTEN : 取两图层全部,点亮交集部分颜色
15.PorterDuff.Mode.MULTIPLY : 取两图层交集部分叠加后颜色
16.PorterDuff.Mode.SCREEN : 取两图层全部区域,交集部分变为透明色

后来还新增了俩种模式 ADD和OVERLAY

17.PorterDuff.Mode.ADD 饱和度叠加

图形绘制中的PorterDuffXfermode_第1张图片

18.PorterDuff.Mode.OVERLAY: 直接叠加


2、示例代码、

下面听过俩个例子来熟悉一下使用

首先来定义一个获取屏幕宽和高的工具代码

<span style="font-size:18px;">public class ScreenMeasureUtil {    //同时获取宽高    public static int[] getScreenHW(Activity activity) {        DisplayMetrics metrics = new DisplayMetrics();        activity.getWindowManager().getDefaultDisplay().getMetrics(metrics);        int Height = metrics.heightPixels;        int Width = metrics.widthPixels;        int HW[] = new int[]{Height, Width};    }    }</span>


橡皮擦效果

自定义一个eraser的view,然后在之布局文件中引入这个控件即可 EraserView.java,注释很详细,这里使用了DST_IN模式(使用dst_out效果一样)

<span style="font-size:18px;">public class EraserView extends View {    //屏幕宽高    private int[] screenSize;    private int screenH;    private int screenW;    //PorterDuff Mode    private static final PorterDuff.Mode PD_MODE = PorterDuff.Mode.DST_IN;    private static final int MIN_MOVE_DIS = 5;//最小的移动距离:如果我们手指在屏幕上的移动距离小于此值则不会绘制    private float preTouchX, preTouchY;    //绘图    private Canvas mCanvas; //画布    private Paint mPaint;//画笔    private Path mPath;//路径    //前后背景    private Bitmap fgBitmap, bgBitmap;    public EraserView(Context context, AttributeSet attrs) {        super(context, attrs);        screenSize = ScreenMeasureUtil.getScreenHW((Activity) context);        screenH = screenSize[0];        screenW = screenSize[1];        initViews(context);    }    private void initViews(Context context) {        //实例化路径对象        mPath = new Path();        //实例化画笔开启抗锯齿和抗抖动        mPaint = new Paint(Paint.ANTI_ALIAS_FLAG | Paint.DITHER_FLAG);        //画笔风格为描边        mPaint.setStyle(Paint.Style.STROKE);        //笔触类型为圆角        mPaint.setStrokeJoin(Paint.Join.ROUND);        //设置描边        mPaint.setStrokeCap(Paint.Cap.ROUND);        //设置描边宽度        mPaint.setStrokeWidth(20);        //设置混合模式        mPaint.setXfermode(new PorterDuffXfermode(PD_MODE));        //此处采用的是DST_IN模式必须要将画笔透明度设置为0        mPaint.setARGB(128, 255, 0, 0);        //前景图片的bitmap        fgBitmap = Bitmap.createBitmap(screenW, screenH, Bitmap.Config.ARGB_8888);        //填充进画布        mCanvas = new Canvas(fgBitmap);        //绘制画布背景颜色为灰色        mCanvas.drawColor(0xffacacac);        //获取底面背景图片        bgBitmap = BitmapFactory.decodeResource(context.getResources(), R.drawable.bg_splash);        //缩放bitmap至屏幕大小        bgBitmap = Bitmap.createScaledBitmap(bgBitmap, screenW, screenH, true);    }    @Override    protected void onDraw(Canvas canvas) {        //绘制背景        canvas.drawBitmap(bgBitmap, 0, 0, null);        //绘制前景        canvas.drawBitmap(fgBitmap, 0, 0, null);        mCanvas.drawPath(mPath, mPaint);    }    @Override    public boolean onTouchEvent(MotionEvent event) {        float x = event.getX();        float y = event.getY();        switch (event.getAction()) {            case MotionEvent.ACTION_DOWN:                mPath.reset();                mPath.moveTo(x, y);                preTouchX = x;                preTouchY = y;                break;            case MotionEvent.ACTION_MOVE:                float dx = Math.abs(x - preTouchX);                float dy = Math.abs(y - preTouchY);                if (dx >= MIN_MOVE_DIS || dy >= MIN_MOVE_DIS) {                    mPath.quadTo(preTouchX, preTouchY, (x + preTouchX) / 2, (y + preTouchY) / 2);                    preTouchX = x;                    preTouchY = y;                }                break;        }        //重绘视图        invalidate();        return true;    }}</span>
图形绘制中的PorterDuffXfermode_第2张图片




更多相关文章

  1. Android 开发中涉及到的设计模式
  2. Android 学习笔记--android――Activity加载模式
  3. Android 官方文档:(一)动画和图像 —— 1.5 画布和画图
  4. android通过USB的MTP模式下,禁止用户在根目录有任何操作(重命名 删
  5. android 启动模式之分析
  6. Activity的启动模式(android:launchMode)
  7. Android Activity加入半透明蒙板,实现夜间模式
  8. Android、Java单例看这里(常用的单例模式对比)
  9. [Android]开启/关闭/监听 飞行模式

随机推荐

  1. Android如何预置数据库或库文件
  2. 如何获取 Android(安卓)设备的CPU核数、
  3. android 下自定义view, android.view.Inf
  4. Android如何获取判断是否有悬浮窗权限
  5. android 沉浸式(透明)状态栏实现
  6. Android(安卓)HIDL官方文档(十)—— Conver
  7. Android(安卓)项目中的小需求
  8. Android学习--界面设计
  9. Android(安卓)CoordinatorLayout之源码解
  10. Android:在AndroidManifest中注册Broadcas