频道栏目
首页 > 资讯 > Android > 正文

Android中Xfermode简单用法

15-04-07        来源:[db:作者]  
收藏   我要投稿

首先在写这篇博客的时候,需要说明我是参考了那篇博文给我的灵感:
详解Paint的setXfermode(Xfermode xfermode)
其次呢,在写这篇博文的时候呢也避免不了抱怨啊。网上其他的关于Xfermode介绍的大部分都是google官方文档中属性的含义,都很雷同估计都是翻译过来的
title=我想说的是就不能有点原创吗?

so,我决定写这篇文章:

一是抒发我心中的纠结; 二是抒发这么多天下文章一大抄就是没有自己出的文章; 三是抄就抄吧,也要加入自己的感悟把;
四是记录一下,以免以后忘记;

另外呢,之前我准备参考源码来写这篇文章的,但是我下载之后没有下载到,android5.1下载的samples里面没有找到apidemo,不知道怎么回事,如果有童鞋知道是怎么回事的,可以和我说说,并且下载下载android5.1的sdk速度飞速啊,但是5.0之后的sdk基本上无响应,下载不了。

下面进入正题吧:
不免俗套的贴上google官方ApiDemo中Graphics中Xfermode截图:
这里写图片描述

纠结了2天终于弄出来的

这里写图片描述

最令人气愤是你看着其他人博客然后想做google官方属性的出的效果,但是愣是没有做出来效果,我这暴脾气,非要弄出来。就是比别人纠结。
title=于是乎有了这篇博文。

有可能是我大脑不行,给出大伙看看其他博文的写法:
他们都是 XxxView extends ImageView然后写的,但是关键点都没有介绍出来。我呢下面会给大家介绍最简单直接的做法,为了方便大伙看明白,简单有效才是王道!!

首先我声明啊,不是恶意攻击和灌水

,只是给大伙对比下,其实我们只需要简简单单的怎么用而不是把全套写法代码都贴出来。点到即止,同时也要让大伙知道怎么用。

 
此处省略百度一大堆文章,全是代码根本不知道他们要说的主要思想是什么……..,不是灌水不是攻击只是给大伙借鉴

下面真正是正文了啊:大伙注意了。
对于官方文档的xfermode我们只是看到两个类似层的图片
其实和photoshop中的图层一样;
一个是原始图层,另一个是遮罩层
我把整个View的画布设置为绿色了,为了方便大家观看效果

canvas.drawColor(Color.GREEN);//画布设为绿色

先上效果图吧,嘿嘿苍老师的头像。

苍老师,哈哈

看完正确运行出来的效果,那么给大家看看错误运行出来的效果:
是我的苍老师,也是大家的苍老师
苍老师出错了

这个是为什么呢title=
最后参照文章开头的链接给大伙看的必须要设置:

//将绘制操作保存到新的图层(离屏缓存)
canvas.saveLayer(0,0,300,300, null,Canvas.ALL_SAVE_FLAG);
方法:
public int saveLayer(float left, float top, float right, float bottom, Paint paint, int saveFlags)

大伙不要小看这个方法,我们必须设置将绘制操作保存到新的图层,不然就会出现苍老师头像显示不正常的情况
当然最后还要还原画布

// 还原画布
canvas.restoreToCount(sc);

canvas顾名思义是画布。所有的绘制操作都发生在这张画布上,当然当我们要使用多个图片叠加等的情况我们就要使用“层”了,就如百度地图或是高德地图,他们在地图上面添加新的事物,如线路,兴趣点的时候都是用到了层Layer。
当然Canvas给我们提供了层支持;这些Layer是按照栈结构来管理的,后进先出的顺序显示;
当Layer入栈的时候,那么后续的drawXXXX操作都发生在这个Layer层上面。而Layer退栈时,就会把本层绘制的图像“绘制”到上层或是Canvas上,在复制Layer到Canvas上时,可以指定Layer的透明度(Layer),这是在创建Layer时指定的:
public int saveLayerAlpha(RectF bounds, int alpha, int saveFlags)
我们这篇就不说明saveLayerAplha了。大伙可以自己使用

那么说这么多,有人看博文肯定说代码呢,稍等,客官马上就来咯:
当然Xfermode网上很多文章都写了相关属性介绍的含义,当然我做这个的时候是按照官方给出图片做的效果。意思呢,可以意会。如果我说了,大伙又迷糊了。哈哈哈哈,这也是我的风格。

那么我所有的操作都在onDraw()函数体里面写了啊。至于性能方面不是我这篇文章所讨论的。可以不用在onDraw里面new对象操作,可以提高性能啥的。
当然自定义view避免不了,先测量下啦。为了简单直接这样:

@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
int width=MeasureSpec.getSize(widthMeasureSpec);
int height=MeasureSpec.getSize(heightMeasureSpec);
setMeasuredDimension(width,height);
}

最后贴上onDraw里面的代码,全部在这了:

@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
canvas.drawColor(Color.GREEN);//设画布绿色
canvas.translate(20,20);//移动画布
// 原始图片
Bitmap src = BitmapFactory.decodeResource(getResources(), R.mipmap.cangcang);
// 图片的遮罩
Bitmap mask=Bitmap.createBitmap(300, 300, src.getConfig());
Canvas cc=new Canvas(mask);
cc.drawCircle(150,150,150,mPaint);
/*
* 离屏缓存
* Layer层的宽和高要设定好,不然会出现有些部位不再层里面,你的操作是不对这些部位起作用的
*/
int sc = canvas.saveLayer(0,0,300,300, null, Canvas.ALL_SAVE_FLAG);
// 先绘制dis目标图
canvas.drawBitmap(src, 0, 0, mPaint);
// 设置混合模式 (只在源图像和目标图像相交的地方绘制目标图像)
mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_IN));
// 再绘制src源图
canvas.drawBitmap(mask, 0, 0, mPaint);
// 还原混合模式
mPaint.setXfermode(null);
// 还原画布
canvas.restoreToCount(sc);
}

那么其他的xfermode属性大家可以自己尝试。前提是Layer的宽度和高度大家要控制好,其他都大同小异。

相关TAG标签
上一篇:android开发环境搭建中容易遇到的问题和疑惑
下一篇:Android MVP 学习
相关文章
图文推荐

关于我们 | 联系我们 | 广告服务 | 投资合作 | 版权申明 | 在线帮助 | 网站地图 | 作品发布 | Vip技术培训 | 举报中心

版权所有: 红黑联盟--致力于做实用的IT技术学习网站