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>

图形绘制中的PorterDuffXfermode的更多相关文章

  1. style在进行图形绘制前,要设置好绘图的样式

    是html5出现的新标签,像所有的dom对象一样它有自己本身的属性.方法和事件,其中就有绘图的方法,js能够调用它来进行绘图 ,最近在研读<html5与css3权威指南>下面对其中最好玩的 ...

  2. python中的turtle库(图形绘画库)

    turtle绘图的基础知识:1. 画布(canvas) 画布就是turtle为我们展开用于绘图区域,我们可以设置它的大小和初始位置. 设置画布大小 turtle.screensize(canvwidt ...

  3. canvas绘制中的API

    canvas绘制Z 先贴代码吧: /** * Created by Administrator on 2016/1/26. */ var i; function draw (id){ var canv ...

  4. 使用Android绘图技术绘制一个椭圆形,然后通过触摸事件让该椭圆形跟着手指移动

    引言:在图形绘制中,控制一个图形(圆形,椭圆形,矩形,三角形)移动时,其实计算的都是该图形的中心点移动.在绘制过程中,首先计算出中心点,然后根据中心点的位置计算重图形的上下左右位置.我们假设图形左边为 ...

  5. Matplotlib基本使用简介

    目录 Matplotlib基本使用简介 1. Matplotlib简介 2. Matplotlib操作简介 Matplotlib基本使用简介 1. Matplotlib简介   Matplotlib是 ...

  6. IOS - 绘制文字 drawInRect: withFont: not working

    在图形绘制中,我们经常会需要绘制文本,但我在给PDF上绘制Text时,始终绘制不上, 使用过: [str drawInRect:cubeRect withAttributes:attrs]; CGCo ...

  7. canvas基础2--绘制图形

    栅格 绘制矩形 不同于SVG,HTML中的元素canvas只支持一种原生的图形绘制:矩形.所有其他的图形的绘制都至少需要生成一条路径.不过,我们拥有众多路径生成的方法让复杂图形的绘制成为了可能. 首先 ...

  8. HTML5:Canvas-绘制图形

    到本文的最后,你将学会如何绘制矩形,三角形,直线,圆弧和曲线,变得熟悉这些基本的形状.绘制物体到Canvas前,需掌握路径,我们看看到底怎么做. 栅格 在我们开始画图之前,我们需要了解一下画布栅格(c ...

  9. Android图形合成和显示系统---基于高通MSM8k MDP4平台

    介绍了Android SurfaceFlinger层次以下的图形合成和显示系统,主要基于高通MSM8k MDP4x平台. 做为Android Display专题.SurfaceFlinger的详细介绍 ...

随机推荐

  1. JDBC线程池创建与DBCP源码阅读

    创建数据库连接是一个比较消耗性能的操作,同时在并发量较大的情况下创建过多的连接对服务器形成巨大的压力.对于资源的频繁分配﹑释放所造成的问题,使用连接池技术是一种比较好的解决方式. 在Java中,连接池 ...

  2. 计算机网络之套接字SOCKET

    当某个应用进程启动系统调用时,控制权就从应用进程传递给了系统调用接口. 此接口再将控制权传递给计算机的操作系统.操作系统将此调用转给某个内部过程,并执行所请求的操作. 内部过程一旦执行完毕,控制权就又 ...

  3. Android Multimedia框架总结(十九)Camera2框架C/S模型之CameraService启动及与Client连接过程

    转载请把头部出处链接和尾部二维码一起转载,本文出自逆流的鱼yuiop:http://blog.csdn.net/hejjunlin/article/details/53150322 Agenda: 一 ...

  4. 一个环形公路,上面有N个站点,A1, ..., AN,其中Ai和Ai+1之间的距离为Di,AN和A1之间的距离为D0。 高效的求第i和第j个站点之间的距离,空间复杂度不超过O(N)。

    //点数 #define N 10 //点间距 int D[N]; //A1到每个Ai的距离 int A1ToX[N]; void preprocess() { srand(time(0)); //随 ...

  5. JAVA面向对象-----成员内部类的访问方式

    成员内部类的访问方式 1.内部类可以直接访问外部类的成员属性.(孙悟空相当于内部类飞到牛魔王的肚子里面去). 2.外部类需要访问内部类的成员属性时需要创建内部类的对象. 1.在外部类的成员函数中创建内 ...

  6. 操作系统服务:OS模块

    http://blog.csdn.net/pipisorry/article/details/52454486 一般的操作系统服务之OS模块Generic Operating System Servi ...

  7. android拍照获得图片及获得图片后剪切设置到ImageView

    ok,这次的项目需要用到设置头像功能,所以做了个总结,直接进入主题吧. 先说说怎么 使用android内置的相机拍照然后获取到这张照片吧 直接上代码: Intent intentFromCapture ...

  8. Dynamics CRM2016 新功能之从CRM APP通过电子邮件发送页面链接

    通过电子邮件发送页面链接在PC端早就有了,但APP端却始终没有,这版加上了这个功能,这里还是以case为例,发送页面链接的方式有两种 第一种在list界面,长按你要share的数据,会出来选项shar ...

  9. 剑指offer面试题4 替换空格(c)

  10. 剑指Offer--图的操作

    剑指Offer–图的操作 前言   企业笔试过程中会涉及到数据结构的方方面面,现将有关图的深度优先搜索与广度优先搜索进行整理归纳,方便日后查阅.   在已做过的笔试题目中,可用DFS解决的题目有: & ...