Android ImageView圆形头像 图片完全解析

我们在做项目的时候会用到圆形的图片,比如用户头像,类似QQ。用户在用QQ更换头像的时候,上传的图片都是矩形的,但显示的时候确是圆形的。

原理:先在canvas上面画一个圆形,参照圆形的起点坐标、 半径,再画一个边长为圆的直径的bitmap(这个bitmap就是你想画的圆形头像),此时圆和bitmap重叠在一起,圆在下面,bitmap在上 面,bitmap覆盖着圆(如下图,其实圆是在bitmap后面的,看不到的。为了形象,我用ps搞了一个半透明圆效果)。

   关键点来了:这时,圆形和bitmap相交的部分正是圆大小的面积,如果能将bitmap与圆相交之外的部分去掉,那么我们看到的是不是bitmap的圆形部分?(如下图蓝色部分)

搞清楚原理后,下面我门来看代码是怎么实现的。

         public Bitmap toRoundBitmap(Bitmap bitmap) {
//圆形图片宽高
int width = bitmap.getWidth();
int height = bitmap.getHeight();
//正方形的边长
int r = 0;
//取最短边做边长
if(width > height) {
r = height;
} else {
r = width;
}
//构建一个bitmap
Bitmap backgroundBmp = Bitmap.createBitmap(width,
height, Config.ARGB_8888);
//new一个Canvas,在backgroundBmp上画图
Canvas canvas = new Canvas(backgroundBmp);
Paint paint = new Paint();
//设置边缘光滑,去掉锯齿
paint.setAntiAlias(true);
//宽高相等,即正方形
RectF rect = new RectF(0, 0, r, r);
//通过制定的rect画一个圆角矩形,当圆角X轴方向的半径等于Y轴方向的半径时,
//且都等于r/2时,画出来的圆角矩形就是圆形
canvas.drawRoundRect(rect, r/2, r/2, paint);
//设置当两个图形相交时的模式,SRC_IN为取SRC图形相交的部分,多余的将被去掉
paint.setXfermode(new PorterDuffXfermode(Mode.SRC_IN));
//canvas将bitmap画在backgroundBmp上
canvas.drawBitmap(bitmap, null, rect, paint);
//返回已经绘画好的backgroundBmp
return backgroundBmp;
}

下面解释一下关键的几行代码:

canvas.drawRoundRect(rect, r/2, r/2, paint);

这行代码是画一个圆角矩形,X、Y方向的圆角半径相等时,且长度为正方形边长的一半时,则画出来的圆角矩形就是圆,如下图:

对于这行代码,大家可以看看这篇文章http://book.51cto.com/art/201204/328272.htm

paint.setXfermode(new PorterDuffXfermode(Mode.SRC_IN));

这行代码是设置图片相交时的模式,这篇文章有一张很好的图说明,http://trylovecatch.iteye.com/blog/1189452

  canvas.drawBitmap(bitmap, null, rect, paint); 

而这行代码则是画一个bitmap到canvas上面去,官方API

参数:src 可以为空,不为空时,canvas将bitmap画到该区域;

如果src和dst的区域不一样,那么bitmap画的地方和显示的地方将不一样,即只能看到一部分bitmap。

其他类似demo:

http://www.tuicool.com/articles/mQNFJ3

转载自:http://m.oschina.net/blog/321024

最新文章

  1. Android 四大组件之Activity(续2)
  2. Angular工作笔记
  3. Redis应用场景(转)
  4. Android 中ViewPagerIndicator的使用
  5. 深入浅出Redis04使用Redis数据库(lists类型)
  6. 防止 SQL 注入的方法(摘抄)
  7. 关于Qt
  8. Spring REST实践之Error Handling
  9. Mysql配置文件my.cnf解析
  10. ecshop订单中配送方式报错
  11. Java多线程中的join()方法
  12. 在Unicode版Inno Setup中使用ISSkin给安装程序添加皮肤
  13. libMobileGestalt与UDID
  14. NHibernate教程(20)——二级缓存(上)
  15. python 中os.path.join 双斜杠的解决办法
  16. Troubleshooting 'library cache: mutex X' Waits. (Doc ID 1357946.1)
  17. Vmware10中Centos7挂载Windows主机的共享文件夹,提示:Error: cannot mount filesystem: No such device
  18. [linux-脚本]shebang(shabang #!)
  19. python+requests库,接口自动化
  20. 官方Canvas API文档

热门文章

  1. Android UI开发第二十六篇——Fragment间的通信
  2. JS复制粘贴解决方案
  3. <block/> 并不是一个组件,它仅仅是一个包装元素,不会在页面中做任何渲染,只接受控制属性
  4. ORACLE日期时间函数
  5. MySQL中B+树索引的使用
  6. python模块学习(一)
  7. 我的Android进阶之旅------>(全解析)屏幕尺寸,分辨率,像素,PPI之间到底什么关系?
  8. 《Python 数据分析》笔记——数据的检索、加工与存储
  9. Java并发—线程池框架Executor总结(转载)
  10. github常用的git命令