观看此篇文章前,请先阅读上篇文章:高仿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头像截取升级版的更多相关文章

  1. 高仿QQ头像截取

    花费了半天时间,把 仿QQ头像截取的方法整理了下,并制作了一个demo以供大家参考,基本上实现了qq中我的资料界面上(包括背景透明化,上滑标题栏显示,下拉隐藏等)的大致效果,先上图看效果吧: 支持的功 ...

  2. Android 高仿微信头像截取 打造不一样的自定义控件

    转载请表明出处:http://blog.csdn.net/lmj623565791/article/details/39761281,本文出自:[张鸿洋的博客] 1.概述 前面已经写了关于检测手势识别 ...

  3. 高仿QQ即时聊天软件开发系列之三登录窗口用户选择下拉框

    上一篇高仿QQ即时聊天软件开发系列之二登录窗口界面写了一个大概的布局和原理 这一篇详细说下拉框的实现原理 先上最终效果图 一开始其实只是想给下拉框加一个placeholder效果,让下拉框在未选择未输 ...

  4. 史上最简单,一步集成侧滑(删除)菜单,高仿QQ、IOS。

    重要的话 开头说,not for the RecyclerView or ListView, for the Any ViewGroup. 本控件不依赖任何父布局,不是针对 RecyclerView. ...

  5. Android实现高仿QQ附近的人搜索展示

    本文主要实现了高仿QQ附近的人搜索展示,用到了自定义控件的方法 最终效果如下 1.下面展示列表我们可以使用ViewPager来实现(当然如果你不觉得麻烦,你也可以用HorizontalScrollVi ...

  6. 高仿QQ的即时通讯应用带服务端软件安装

    Android 基于xmpp协议,smack包,openfire服务端(在下面)的高仿QQ的即时通讯实现.实现了注册,登录,读取好友列表,搜索好友,添加分组,添加好友,删除好友,修改心情,两个客户端之 ...

  7. 高仿QQ即时聊天软件开发系列之二登录窗口界面

    继上一篇高仿QQ即时聊天软件开发系列之一开端之后,开始做登录窗口 废话不多说,先看效果,只有界面 可能还有一些细节地方没有做,例如那个LOGO嘛,不要在意这些细节 GIF虽短,可是这做起来真难,好吧因 ...

  8. 高仿QQ即时聊天软件开发系列之一开端

    前段时间在园子里看到一个大神做了一个GG2014IM软件,仿QQ的,那感觉···,赶快下载源码过来试试,还真能直接跑起来,效果也不错.但一看源码,全都给封装到了ESFramework里面了,音视频那部 ...

  9. 高仿qq聊天界面

    高仿qq聊天界面,给有需要的人,界面效果如下: 真心觉得做界面非常痛苦,给有需要的朋友. chat.xml <?xml version="1.0" encoding=&quo ...

随机推荐

  1. ●BZOJ 3640 JC的小苹果

    题链: http://www.lydsy.com/JudgeOnline/problem.php?id=3640题解: 期望dp,高斯消元 设dp[i][h]在i位置且血量为h这个状态的期望经过次数. ...

  2. 洛谷P3168 [CQOI2015]任务查询系统

    #include<cstdio> #include<cstdlib> #include<algorithm> #include<cstring> #in ...

  3. bzoj1926[Sdoi2010]粟粟的书架 二分 主席树

    1926: [Sdoi2010]粟粟的书架 Time Limit: 30 Sec  Memory Limit: 552 MBSubmit: 1064  Solved: 421[Submit][Stat ...

  4. [bzoj1143][CTSC2008]祭祀

    题意:给定一个n个点m条边的有向无环图,你要选出最多的点,并且满足任意两点之间都不存在通路.2)输出每个点选了它之后还是否有最优解.   n<=100 m<=1000 题解:每个点拆两个点 ...

  5. RxSwift 系列(八) -- Error Handing Operators

    前言 本篇文章我们将学习RxSwift中的错误处理,包括: catchErrorJustReturn catchError retry retry(_:) catchErrorJustReturn 遇 ...

  6. jieba库分词统计

    代码在github网站,https://github.com/chaigee/chaigee,中的z3.py文件 py.txt为团队中文简介文件 代码运行后词频统计使用xlwt库将数据发送到excel ...

  7. MySQL使用判断

    1.case语法 在第一个方案的返回结果中, value=compare-value.而第二个方案的返回结果是第一种情况的真实结果.如果没有匹配的结果值,则返回结果为ELSE后的结果,如果没有ELSE ...

  8. kibana使用

    最近,被老大叫写一个kibana的使用方法给所有人用. 注意的一点: 能不用空格表示OR或者AND就不用空格表示,因为要么全用要么全部不用,否则会因为解析搜索同级的时候,若出现空格和OR,会冲突覆盖意 ...

  9. 基于PHP的地址清洗调用案例-快宝开放平台

    快宝地址清洗,纠正错误地址.识别不完整地址.地址补全,并输出结构化地址数据的通用解决方案.广泛应用于快递行业,电商行业,ERP应用等. 快宝开放平台-地址清洗对接API:http://open.kua ...

  10. 各种异常 及异常类和Object类

    Day05 异常 Object类 equals方法,用于比较两个对象是否相同,它其实就是使用两个对象的内存地址在比较.Object类中的equals方法内部使用的就是==比较运算符. 2. 描述人这个 ...