花费了半天时间,把 仿QQ头像截取的方法整理了下,并制作了一个demo以供大家参考,基本上实现了qq中我的资料界面上(包括背景透明化,上滑标题栏显示,下拉隐藏等)的大致效果,先上图看效果吧:
支持的功能:
1.选择裁剪的图片支持手势放大缩小(包括双击放大缩小);
2.判断图片边缘,即裁剪区域不会超过图片边缘;
原理:
一个重写的RelativeLayout,里面放了两层View,下层是重写的支持缩放的ImageView用于放置选择裁剪的图片,ImageView上层是一个自定义View,通过onDraw画上去的一个白色的圆圈圈代表裁剪区域;事实上,在本demo中,当你点击确定 时,裁剪下来的是一个正方形的区域,如下图:
裁剪出的正方形bitmap方法(mHorizontalPadding为裁剪区离屏幕左右的距离,mVerticalPadding为裁剪区离屏幕上下的距离):
Bitmap bitmap = Bitmap.createBitmap(getWidth(), getHeight(),Bitmap.Config.ARGB_8888); Canvas canvas = new Canvas(bitmap); draw(canvas); //若为裁剪为方形区域,则去掉getCircleBitmap方法即可 return getCircleBitmap(Bitmap.createBitmap(bitmap, mHorizontalPadding, mVerticalPadding, getWidth() - 2 * mHorizontalPadding, getWidth() - 2 * mHorizontalPadding));
只是将最终生成的方形bitmap转换为了圆形的bitmap:
/** * 将方形bitmap转换为圆形bitmap * @param bitmap * @return */ private Bitmap getCircleBitmap(Bitmap bitmap) { Bitmap output = Bitmap.createBitmap(bitmap.getWidth(),bitmap.getHeight(), Config.ARGB_8888); Canvas canvas = new Canvas(output); final int color = 0xff424242; final Rect rect = new Rect(0, 0, bitmap.getWidth(), bitmap.getHeight()); Paint paint =new Paint(); paint.setAntiAlias(true); canvas.drawARGB(0, 0, 0, 0); paint.setColor(color); int x = bitmap.getWidth(); canvas.drawCircle(x / 2, x / 2, x / 2, paint); paint.setXfermode(new PorterDuffXfermode(Mode.SRC_IN)); canvas.drawBitmap(bitmap, rect, rect, paint); return output; }
ClipImageLayout中有一个变量是mHorizontalPadding,此为裁剪区圆形边界距离屏幕边缘的距离,值越大,裁剪区域就越小,反之越大(当然不能小于0);
需要注意的是:
在裁剪界面ClipActivity,需要加上
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,WindowManager.LayoutParams.FLAG_FULLSCREEN)
以防止不同手机的通知栏高度会影响判断裁剪区域是否超出图片范围的准确性;
并且,裁剪界面是将选择的图片转换为bitmap进行显示的,如果资源过大,会导致内存溢出,所以还需要进行一步压缩:
Bitmap bitmap=ImageTools.convertToBitmap(path, 600,600);
另:如若想改为裁剪方形头像,则可将裁剪界面裁剪区域边框改为正方形即可:
//方形边框 // canvas.drawRect(mHorizontalPadding, mVerticalPadding, getWidth()- mHorizontalPadding, getHeight() - mVerticalPadding, mPaint); //圆形边框 canvas.drawCircle( getWidth()/2, getHeight()/2, getWidth()/2-mHorizontalPadding, mPaint);
并在裁剪后生成的bitmap方法中去掉将其 转换为圆形bitmap的方法即可,代码中注释的也非常清楚。
源码奉上:http://download.csdn.net/detail/baiyuliang2013/8467647