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 饱和度叠加


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>




更多相关文章

  1. cocos2dx程序 在android上 触碰屏幕就崩溃 crash in cocos on to
  2. Android(安卓)笔记
  3. Android(安卓)- 绘画出圆并保存为图片(详)
  4. Android(安卓)自定义View及其在布局文件中的使用示例(二)
  5. Android事件分发和View绘制流程分析(三)
  6. [Android]googleMap的简单使用,地图定位,图标绘制。
  7. Android(安卓)技术提升总结(持续更新)
  8. Android的简单图形和view刷新
  9. android酷炫翻页效果+图形分析

随机推荐

  1. 《Android(安卓)JNI》05 在JNI中调用Java
  2. Android(安卓)Info类的总结
  3. Android(安卓)aapt自动打包工具详细介绍
  4. Android源码下载小结
  5. Android悬浮通知无效的问题
  6. Android(安卓)判断手机是否安装某个应用
  7. 无法在Android(安卓)Studio中设置断点
  8. Android(安卓)通过ViewPager实现广告轮播
  9. Android(安卓)DatePicker和TimePicker案
  10. 安卓新技术学习资料整理 常更新哦~