关于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下,画一个圆形的下层图,再把目标图片画在上面,那么这样最后的结果就是圆形图片(取绘制的图的交集部分,显示上层)。

代码示例:

[java]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. public static Bitmap getRoundedCornerBitmap(Bitmap srcBitmap) {  
  2.   
  3.        int width = srcBitmap.getWidth();  
  4.        int height = srcBitmap.getHeight();  
  5.   
  6.        int radius = 0;  
  7.        if (width <= height) {  
  8.            radius = width / 2;  
  9.        } else {  
  10.            radius = height / 2;  
  11.        }  
  12.   
  13.        Paint paint = new Paint();  
  14.        paint.setAntiAlias(true);  
  15.        paint.setDither(true);  
  16.        paint.setColor(Color.WHITE);  
  17.   
  18.        Rect rect = new Rect(002 * radius, 2 * radius);  
  19.        RectF rectF = new RectF(rect);  
  20.        Bitmap desBitmap = Bitmap.createBitmap(2 * radius, 2 * radius, Bitmap.Config.ARGB_4444);  
  21.        Canvas canvas = new Canvas(desBitmap);  
  22.        //除去抗锯齿  
  23.        canvas.setDrawFilter(new PaintFlagsDrawFilter(0, Paint.ANTI_ALIAS_FLAG | Paint.FILTER_BITMAP_FLAG));  
  24.        canvas.drawARGB(0000);  
  25.        //绘制下层图  
  26.        canvas.drawRoundRect(rectF, radius, radius, paint);  
  27.        // 设置PorterDuffXfermode模式,取绘制的图的交集部分,显示上层  
  28.        paint.setXfermode(new PorterDuffXfermode(Mode.SRC_IN));  
  29.        //绘制上层图  
  30.        canvas.drawBitmap(srcBitmap, rect, rect, paint);  
  31.   
  32.        return desBitmap;  
  33.    }  


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值