安卓高仿QQ头像截取升级版
观看此篇文章前,请先阅读上篇文章:高仿QQ头像截取;
本篇之所以为升级版,是在截取头像界面添加了与qq类似的阴影层(裁剪区域以外的部分),且看效果图:
为了适应大家不同需求,这次打了两个包,及上图中一个方形的头像截取demo和一个圆形的;
原理:
方形:
如图:底层即图片层,在上层的画布中,先将裁剪区四周根据裁剪区大小画上阴影,然后在画上裁剪区的白色边框(空心):如下图
主要代码如下:
@Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); // 计算矩形区域的宽度 mWidth = getWidth() - 2 * mHorizontalPadding; // 计算距离屏幕垂直边界 的边距 mVerticalPadding = (getHeight() - mWidth) / 2; // 绘制左边 canvas.drawRect(0, 0, mHorizontalPadding, getHeight()-mVerticalPadding, mPaintRect); // 绘制右边 canvas.drawRect(getWidth() - mHorizontalPadding, mVerticalPadding, getWidth(),getHeight(), mPaintRect); // 绘制上边 canvas.drawRect(mHorizontalPadding, 0, getWidth(),mVerticalPadding, mPaintRect); // 绘制下边 canvas.drawRect(0, getHeight() - mVerticalPadding,getWidth() - mHorizontalPadding, getHeight(), mPaintRect); //绘制边框 canvas.drawRect( mHorizontalPadding, mVerticalPadding,mHorizontalPadding+mWidth, mVerticalPadding+mWidth, mPaint); }
圆形:
圆形裁剪稍复杂一点,利用到了Xfermode即图像重叠模式中的XOR:抠出重叠区域
实现思路:
画的有点乱,先凑合着看,2,3是用的另一个画布,并将3即实心圆的画笔设置为:
mPaintCirle.setXfermode(new PorterDuffXfermode(Mode.XOR));
当阴影层和其上部的的实心圆重叠时,则实心圆部分即被抠出,剩下一个中间空洞的阴影层了,然后再将该画布的bitmap画在自定义View的画布上合成,最后画出圆形裁剪区白色边框,主要代码如下:
protected void onDraw(Canvas canvas) { super.onDraw(canvas); if(mBgBitmap==null){ mBgBitmap = Bitmap.createBitmap(getWidth(), getHeight(), Config.ARGB_8888); mCanvas = new Canvas(mBgBitmap); mRect = new RectF(0, 0, getWidth(), getHeight()); } //绘制阴影层 mCanvas.drawRect(mRect, mPaintRect); //绘制实心圆 ,绘制完后,在mCanvas画布中,mPaintRect和mPaintCirle相交部分即被掏空 mCanvas.drawCircle( getWidth()/2, getHeight()/2, getWidth()/2-mHorizontalPadding, mPaintCirle); //将阴影层画进本View的画布中 canvas.drawBitmap(mBgBitmap, null, mRect, new Paint()); //绘制圆环 canvas.drawCircle( getWidth()/2, getHeight()/2, getWidth()/2-mHorizontalPadding, mPaint); }
好了,且看源码下载地址,两个demo都包含在内:
http://download.csdn.net/detail/baiyuliang2013/8469585
PS:看到有些同学想把图像缩放到裁剪框内,可以进行以下操作:
在ClipActivity中,对图片进行bitmap缩放转换这一步Bitmap bitmap=ImageTools.convertToBitmap之上,加上代码:
int mHorizontalPadding = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 60, getResources().getDisplayMetrics()); WindowManager windowManager = getWindowManager(); Display display = windowManager.getDefaultDisplay(); int width=display.getWidth()-2*mHorizontalPadding;
然后将Bitmap bitmap=ImageTools.convertToBitmap修改为:
Bitmap bitmap=ImageTools.convertToBitmap(path, width,width);
这样做的目的是在选择完图片进行初始化时,图片宽或高正好卡在裁剪框内,效果如图:
其中60表示你定义的裁剪框离屏幕边缘的宽度。
2015-07-09更新:
在实际使用过程中,某些手机如小米三星等,在裁剪界面抠图以外的透明区域会很暗甚至看上去就是黑色的,给用户的体验很不好,在多次尝试之后,得到了一个方法如下:
//绘制阴影层 mPaintRect = new Paint(); mPaintRect.setColor(Color.parseColor("#30000000")); // mPaintRect.setARGB(70, 0,0, 0); // 绘制实心圆 mPaintCirle = new Paint(); mPaintCirle.setStrokeWidth((getWidth()-2*mHorizontalPadding)/2); //实心圆半径 mPaintCirle.setARGB(255, 0,0, 0); // 绘制实心圆2 mPaintCirle2 = new Paint(); mPaintCirle2.setStrokeWidth((getWidth()-2*mHorizontalPadding)/2); //实心圆半径 mPaintCirle2.setARGB(255, 0,0, 0); mPaintCirle2.setXfermode(new PorterDuffXfermode(Mode.XOR));//XOR模式:重叠部分被掏空
也就是多绘制一个实心圆:
mCanvas.drawCircle( getWidth()/2, getHeight()/2, getWidth()/2-mHorizontalPadding, mPaintCirle); mCanvas.drawCircle( getWidth()/2, getHeight()/2, getWidth()/2-mHorizontalPadding, mPaintCirle2);
设置阴影层透明度时可以使用setARGB方法设置透明度(0-255数值越小越透明),或者设置画笔颜色为透明色:
效果如下:
是不是较之前效果好了很多呢?!那么现在就可以根据自己的需要去调节自己想要的效果啦!
2015-10-12:
最近有童鞋想要长方形的效果,其实很简单,修改(计算)下裁剪区和边框区屏幕顶部到上边框(以及屏幕底部到下边框)的距离就行了:
示意图:
红色是原来正方形区域,蓝色为长方形区域。
修改裁剪区mVerticalPadding计算方法:
修改浮层白色边框及阴影显示区域的计算方法:
以上修改后的宽高比为2:1,效果图:
只需要注意这几个修改的地方,自行修改为自己想要的比例!
安卓高仿QQ头像截取升级版的更多相关文章
- 高仿QQ头像截取
花费了半天时间,把 仿QQ头像截取的方法整理了下,并制作了一个demo以供大家参考,基本上实现了qq中我的资料界面上(包括背景透明化,上滑标题栏显示,下拉隐藏等)的大致效果,先上图看效果吧: 支持的功 ...
- Android 高仿微信头像截取 打造不一样的自定义控件
转载请表明出处:http://blog.csdn.net/lmj623565791/article/details/39761281,本文出自:[张鸿洋的博客] 1.概述 前面已经写了关于检测手势识别 ...
- 高仿QQ即时聊天软件开发系列之三登录窗口用户选择下拉框
上一篇高仿QQ即时聊天软件开发系列之二登录窗口界面写了一个大概的布局和原理 这一篇详细说下拉框的实现原理 先上最终效果图 一开始其实只是想给下拉框加一个placeholder效果,让下拉框在未选择未输 ...
- 史上最简单,一步集成侧滑(删除)菜单,高仿QQ、IOS。
重要的话 开头说,not for the RecyclerView or ListView, for the Any ViewGroup. 本控件不依赖任何父布局,不是针对 RecyclerView. ...
- Android实现高仿QQ附近的人搜索展示
本文主要实现了高仿QQ附近的人搜索展示,用到了自定义控件的方法 最终效果如下 1.下面展示列表我们可以使用ViewPager来实现(当然如果你不觉得麻烦,你也可以用HorizontalScrollVi ...
- 高仿QQ的即时通讯应用带服务端软件安装
Android 基于xmpp协议,smack包,openfire服务端(在下面)的高仿QQ的即时通讯实现.实现了注册,登录,读取好友列表,搜索好友,添加分组,添加好友,删除好友,修改心情,两个客户端之 ...
- 高仿QQ即时聊天软件开发系列之二登录窗口界面
继上一篇高仿QQ即时聊天软件开发系列之一开端之后,开始做登录窗口 废话不多说,先看效果,只有界面 可能还有一些细节地方没有做,例如那个LOGO嘛,不要在意这些细节 GIF虽短,可是这做起来真难,好吧因 ...
- 高仿QQ即时聊天软件开发系列之一开端
前段时间在园子里看到一个大神做了一个GG2014IM软件,仿QQ的,那感觉···,赶快下载源码过来试试,还真能直接跑起来,效果也不错.但一看源码,全都给封装到了ESFramework里面了,音视频那部 ...
- 高仿qq聊天界面
高仿qq聊天界面,给有需要的人,界面效果如下: 真心觉得做界面非常痛苦,给有需要的朋友. chat.xml <?xml version="1.0" encoding=&quo ...
随机推荐
- 洛谷mNOIP模拟赛Day2-星空
题目背景 pdf题面和大样例链接:http://pan.baidu.com/s/1cawM7c 密码:xgxv 命运偷走如果只留下结果, 时间偷走初衷只留下了苦衷. 你来过,然后你走后,只留下星空. ...
- POJ1222熄灯问题
千年老题,以前用枚举做,现在用高斯消元做 自由元直接做成0即可 #include<cstdio> #include<cstdlib> #include<algorithm ...
- bzoj 2229: [Zjoi2011]最小割
Description 小白在图论课上学到了一个新的概念--最小割,下课后小白在笔记本上写下了如下这段话: "对于一个图,某个对图中结点的划分将图中所有结点分成两个部分,如果结点s,t不在同 ...
- bzoj 2594: [Wc2006]水管局长数据加强版
Description SC省MY市有着庞大的地下水管网络,嘟嘟是MY市的水管局长(就是管水管的啦),嘟嘟作为水管局长的工作就是:每天供水公司可能要将一定量的水从x处送往y处,嘟嘟需要为供水公司找到一 ...
- k-d树模板(BZOJ2648)
实现了插入一个点,查询距某个位置的最近点. #include <cstdio> #include <algorithm> using namespace std; , inf ...
- Python基础学习(第三周)
集合的操作 集合是一个无序的,不重复的数据组合,它的主要作用如下: 去重,把一个列表变成集合,就自动去重了 关系测试,测试两组数据之间的交集,差集,并集等关系 集合的写法 list_1 = set([ ...
- Python中byte与str
原文传送门:请点击 现在计算机中,在内存中采用unicode编码方式. 可以看到上图中,字节型数据t并没有像想象中的一样显示0,1字符串.显示仍然是b,这是因为t是采用utf-8来编码,而utf-8与 ...
- Java并发之BlockingQueue的使用
Java并发之BlockingQueue的使用 一.简介 前段时间看到有些朋友在网上发了一道面试题,题目的大意就是:有两个线程A,B, A线程每200ms就生成一个[0,100]之间的随机数, B线 ...
- 罗列Linux发行版的基础目录名称,命令法则和功能
罗列Linux发行版的基础目录名称命名法则及功用规定 目录描述 /主层次 的根,也是整个文件系统层次结构的根目录 /bin存放在单用户模式可用的必要命令二进制文件,所有用户都可用,如 cat.ls.c ...
- salesforce lightning零基础学习(三) 表达式的!(绑定表达式)与 #(非绑定表达式)
在salesforce的classic中,我们使用{!expresion}在前台页面展示信息,在lightning中,上一篇我们也提及了,如果展示attribute的值,可以使用{!v.expresi ...