PorterDuff及Xfermode详解

使用Paint绘画的时候,需要对Paint设置渲染效果. 不同的渲染效果可以实现不同的叠加或者清除效果, PorterDuff.Mode为枚举类,一共有16个枚举值:

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
取两图层全部区域,交集部分变为透明色

以下是不同组合的测试结果
测试代码如下, mSrcPaint 画了一个圆, mDstPaint画了一个矩形, 然后是调节不同的渲染效果所得的图形结果

    private void draw(Context context) {

        WindowManager manager = (WindowManager)context.getSystemService(Context.WINDOW_SERVICE);
        width = manager.getDefaultDisplay().getWidth();
        height = manager.getDefaultDisplay().getHeight();
        mBitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
        mCanvas = new Canvas(mBitmap);
        Rect rect = new Rect();
        rect.set(200, 500, 600, 950);
        mCanvas.drawCircle(600, 500, 300, mSrcPaint);
        mCanvas.drawRect(rect, mDstPaint);
    }


    private void initSrcPaint() {
        mSrcPaint = new Paint();
        mSrcPaint.setAntiAlias(true);
        mSrcPaint.setDither(true);
        mSrcPaint.setColor(Color.BLUE);
        mSrcPaint.setStyle(Paint.Style.FILL);
        mSrcPaint.setStrokeJoin(Paint.Join.ROUND);
        mSrcPaint.setStrokeCap(Paint.Cap.ROUND);
        mSrcPaint.setStrokeWidth(20);
        mSrcPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC));
    }

    private void initDstPaint() {
        mDstPaint = new Paint();
        mDstPaint.setAntiAlias(true);
        mDstPaint.setDither(true);
        mDstPaint.setColor(Color.YELLOW);
        mDstPaint.setStyle(Paint.Style.FILL);
        mDstPaint.setStrokeJoin(Paint.Join.ROUND);
        mDstPaint.setStrokeCap(Paint.Cap.ROUND);
        mDstPaint.setStrokeWidth(20);
        mDstPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_OVER));
    }
  1. PorterDuff.Mode.SRC
    如果只是绘画圆形得到的结果是, 除了自己绘画的图像之外, 会把背景bitmap填充黑色
    这里写图片描述
    同时如果绘画矩形, 设置以下三个效果和上图一样
    PorterDuff.Mode.DST_OUT, PorterDuff.Mode.DST, PorterDuff.Mode.DST_IN
    如果设置PorterDuff.Mode.DST_OVER 和PorterDuff.Mode.DST_ATOP
    效果是下图
    这里写图片描述

  2. PorterDuff.Mode.SRC_OVER
    绘画圆形的结果是这里写图片描述
    对矩形画笔设置以下渲染效果结果和上图一样
    PorterDuff.Mode.DST, PorterDuff.Mode.DST_IN

如果设置PorterDuff.Mode.DST_OVER 和PorterDuff.Mode.DST_ATOP
PorterDuff.Mode.OVERLAY效果如下
这里写图片描述
矩形也被绘制出来,只是现实在圆形的下面

如果设置PorterDuff.Mode.DST_OUT,
效果如下:
这里写图片描述
矩形是透明的, 并且圆形相交的部分也被透明了, 这效果常常被当橡皮擦使用
PorterDuff.Mode.CLEAR 也可以实现这个效果

PorterDuff.Mode.DARKEN的效果如下
这里写图片描述
保留双方图片, 相交加深色

PorterDuff.Mode.MULTIPLY的效果如下:
这里写图片描述
保留src的图片, 对dst和src相交的部分加深

PorterDuff.Mode.ADD,
PorterDuff.Mode.LIGHTEN,
PorterDuff.Mode.SCREEN的效果如下:
这里写图片描述
保留双方图形, 相交部分颜色减轻

PorterDuff.Mode.XOR的效果如下:
这里写图片描述
保留双方图形, 相交部分变透明

  1. PorterDuff.Mode.SRC_IN
    效果图如下
    这里写图片描述
    什么也没有显示出来.
    对矩形画笔设置以下效果结果和上图一样:
    PorterDuff.Mode.DST
    PorterDuff.Mode.DST_IN
    PorterDuff.Mode.DST_OUT
    orterDuff.Mode.MULTIPLY
    剩下的全部是以下效果
    这里写图片描述

  2. PorterDuff.Mode.SRC_ATOP
    选择此效果的画笔不会显示出来
    这里写图片描述
    PorterDuff.Mode.DST
    PorterDuff.Mode.DST_IN
    PorterDuff.Mode.DST_OUT
    PorterDuff.Mode.MULTIPLY
    PorterDuff.Mode.CLEAR
    都是一样的效果.

剩下的渲染效果都可以讲矩形绘出
这里写图片描述

  1. PorterDuff.Mode.SRC_OUT
    这样的渲染模式下, 背景色加深, 没有任何图形
    这里写图片描述
    无论dst使用何种渲染效果都没有任何图形出现
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
我不确定是否有能自动进行Xfermode混合的Android layout源码,因为这需要在代码中手动实现Xfermode混合。但是,在Android中可以使用PorterDuff.Mode来进行混合,而且在XML布局文件中也可以使用PorterDuff.Mode来设置混合模式。以下是一个使用PorterDuff.Mode进行混合的示例代码: ```xml <RelativeLayout android:id="@+id/relativeLayout" android:layout_width="match_parent" android:layout_height="match_parent" android:background="@android:color/white"> <ImageView android:id="@+id/imageView1" android:layout_width="100dp" android:layout_height="100dp" android:src="@drawable/image1" android:layout_alignParentLeft="true" android:layout_centerVertical="true"/> <ImageView android:id="@+id/imageView2" android:layout_width="100dp" android:layout_height="100dp" android:src="@drawable/image2" android:layout_alignParentRight="true" android:layout_centerVertical="true"/> <View android:layout_width="match_parent" android:layout_height="match_parent" android:background="@android:color/transparent" android:layout_alignTop="@id/imageView1" android:layout_alignBottom="@id/imageView1" android:layout_toRightOf="@id/imageView1" android:layout_toLeftOf="@id/imageView2" android:foreground="@drawable/porter_duff_mode"/> </RelativeLayout> ``` 在上面的示例中,我们创建了一个RelativeLayout,其中包含了两个ImageView和一个View。View的背景设置为透明,前景设置为一个drawable资源文件,其中定义了混合模式: ```xml <selector xmlns:android="http://schemas.android.com/apk/res/android"> <item android:drawable="@drawable/porter_duff_mode_multiply" android:state_pressed="true" /> <item android:drawable="@drawable/porter_duff_mode_screen" android:state_focused="true" /> <item android:drawable="@drawable/porter_duff_mode_overlay" /> </selector> ``` 在这个drawable资源文件中,我们使用了三个不同的混合模式:Multiply、Screen和Overlay。您可以根据需要更改这些模式。通过设置不同的状态,例如“pressed”和“focused”,您可以在不同的情况下使用不同的混合模式。 PorterDuff.Mode提供了很多不同的混合模式,您可以根据需要选择不同的模式。如果您需要更高级的Xfermode混合功能,您可能需要在代码中手动实现它。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值