关于Xfermode的介绍和用处(遮罩图层,圆形图片)

1.关于Xfermode类


从上面看出Xfermode有三个子类:AvoidXfermode,PixelXorXfermode,PoterDuffXfermode。它们分别表示:

AvoidXfermode:在绘图时,要么绘制在最顶层,要么绘制在除最顶层以外的地方。

PixelXorXfermode:这种转换不遵循自左乘的约定,因此这种模式总返回不透明的颜色(alpha=255),由此,对于混合颜色操作是没有用的。

PoterDuffXfermode:可以使用图像合成的任何一条PoterDuff模式。

注意:只有当一个Xfermode被分配给一个Paint时,使用Paint绘制Xfermode才有效。

2.PoterDuffXfemode

关于PoterDuff的所有Mode的效果图如下:


16种模式表示的意思分别是:

PoterDuff.Mode.CLEAR:绘制的图不会提交到画布上

PoterDuff.Mode.SRC:只显示绘制的上层图

PoterDuff.Mode.DST:只显示绘制的下层图

PoterDuff.Mode.SRC_OVER:绘制的上层图和下层图都显示,但上层图会覆盖下层图

PoterDuff.Mode.DST_OVER:绘制的上层图和下层图都显示,但下层图会覆盖上层图

PoterDuff.Mode.SRC_IN:取绘制的图的交集部分,显示上层

PoterDuff.Mode.DST_IN:取绘制的图的交集部分,显示下层

PoterDuff.Mode.SRC_OUT:取绘制的图的非交集部分,显示上层

PoterDuff.Mode.DST_OUT:取绘制的图的非交集部分,显示下层

PoterDuff.Mode.SRC_ATOP:取绘制的图的下层部分,和上层与下层的交集部分

PoterDuff.Mode.DST_ATOP:取绘制的图的上层部分,和下层与上层的交集部分

PoterDuff.Mode.XOR:取绘制的图的上层和下层的非交集部分

PoterDuff.Mode.DARKEN:取绘制的图的全集,上层和下层交集部分加深

PoterDuff.Mode.LIGHTEN:取绘制的图的全集,上层和下层交集部分点亮

PoterDuff.Mode.MULTIPLY:取绘制的图的交集部分并且交集部分颜色加深

PoterDuff.Mode.SCREEN:取绘制的图的全集,上层和下层的交集部分透明

附加:关于图的示例来自于SDK中的Sample,在我电脑上的路劲为:\sdk\samples\android-16\ApiDemos\src\com\example\android\apis\graphics\Xfermode.java

3.运用示例:

 3.1 拍照遮罩  

         先看效果图:


总体为一个FramLayout,遮罩层在相机预览的上面,为了实现这个效果,最核心的就是在画遮罩层的时候,让中间矩形这块区域不可见。那么从上面分析的PoterDuff.Mode中,很明显CLEAR模式下,可以实现上面的效果。

因此,只需要两步,第一步画一个整体的遮罩图(下层图),第二步画一个不显示的矩形图(上层图):

设置画矩形区域的画笔: mRectPaint.setXfermode(new PorterDuffXfermode(android.graphics.PorterDuff.Mode.CLEAR));

在onDraw()方法中,先画下层图: canvas.drawRect(0, 0, mScreenWidth, mScreenHeight, mAreaPaint);,再画上层图:canvas.drawRect(mVisibleRect, mRectPaint);

因此,这样就可以实现上面的显示效果。

   3.2 圆形图片

         先看效果图:

         思路:在PoterDuff.Mode的SRC_IN下,画一个圆形的下层图,再把目标图片画在上面,那么这样最后的结果就是圆形图片(取绘制的图的交集部分,显示上层)。

代码示例:

 public static Bitmap getRoundedCornerBitmap(Bitmap srcBitmap) {

        int width = srcBitmap.getWidth();
        int height = srcBitmap.getHeight();

        int radius = 0;
        if (width <= height) {
            radius = width / 2;
        } else {
            radius = height / 2;
        }

        Paint paint = new Paint();
        paint.setAntiAlias(true);
        paint.setDither(true);
        paint.setColor(Color.WHITE);

        Rect rect = new Rect(0, 0, 2 * radius, 2 * radius);
        RectF rectF = new RectF(rect);
        Bitmap desBitmap = Bitmap.createBitmap(2 * radius, 2 * radius, Bitmap.Config.ARGB_4444);
        Canvas canvas = new Canvas(desBitmap);
        //除去抗锯齿
        canvas.setDrawFilter(new PaintFlagsDrawFilter(0, Paint.ANTI_ALIAS_FLAG | Paint.FILTER_BITMAP_FLAG));
        canvas.drawARGB(0, 0, 0, 0);
        //绘制下层图
        canvas.drawRoundRect(rectF, radius, radius, paint);
        // 设置PorterDuffXfermode模式,取绘制的图的交集部分,显示上层
        paint.setXfermode(new PorterDuffXfermode(Mode.SRC_IN));
        //绘制上层图
        canvas.drawBitmap(srcBitmap, rect, rect, paint);

        return desBitmap;
    }


总结:关于Xfermode的运用还很多,上面遮罩图层和圆形图片只是两种比较常见的运用,从中也可以看出其图像合成的强大所在。另外关于PorterDuff的由来是有两个人名的组合: Thomas Porter 和 Tom Duff。


  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值