您的位置:首页 > Web前端

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

2016-11-24 10:33 423 查看
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

 





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。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: