圆形头像现在很流行了,Github上也有很多开源的库,最经典的是直接使用一个自定义的圆形ImageViwe,比较有代表性的有这个项目:hdodenhof/CircleImageView。但是,如果你的项目中正好使用Picasso作为图片异步加载的话,可以直接使用Picasso原生的Transformation机制,它允许你在显示图片前做一些转化。

为了避免重复造轮子,先Google大法一下,会发现2个比较多人start的gist:
aprock/RoundedTransformation.java
julianshen/CircleTransform.java

第一个RoundedTransformation主要是绘制圆角图形,并且没有处理长方形图片的情况:

@Override
public Bitmap transform(final Bitmap source) {final Paint paint = new Paint();paint.setAntiAlias(true);paint.setShader(new BitmapShader(source, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP));Bitmap output = Bitmap.createBitmap(source.getWidth(), source.getHeight(), Config.ARGB_8888);Canvas canvas = new Canvas(output);canvas.drawRoundRect(new RectF(margin, margin, source.getWidth() - margin, source.getHeight() - margin), radius, radius, paint);if (source != output) {source.recycle();}return output;
}

我们来看看第二个CircleTransform的代码,是绘制圆形图片,并且有处理长方形图片截取中间部分的逻辑。

@Override
public Bitmap transform(Bitmap source) {int size = Math.min(source.getWidth(), source.getHeight());int x = (source.getWidth() - size) / 2;int y = (source.getHeight() - size) / 2;Bitmap squaredBitmap = Bitmap.createBitmap(source, x, y, size, size);if (squaredBitmap != source) {source.recycle();}Bitmap bitmap = Bitmap.createBitmap(size, size, source.getConfig());Canvas canvas = new Canvas(bitmap);Paint paint = new Paint();BitmapShader shader = new BitmapShader(squaredBitmap, BitmapShader.TileMode.CLAMP, BitmapShader.TileMode.CLAMP);paint.setShader(shader);paint.setAntiAlias(true);float r = size/2f;canvas.drawCircle(r, r, r, paint);squaredBitmap.recycle();return bitmap;
}

可以看到上面的两个gist比较核心的一点都是使用BitmapShader来绘制圆形图片,其中TileMode.CLAMP表示对绘制区域进行着色的模式,它会在超出图片边界的时候拉伸图片最后的那一行(列)像素。

其实第二个gist基本能满足需求了。但是还有一点美中不足,中间创建多了一次square bitmap,他的作用主要是先把长方形的图像转为正方形(居中截取),然后再以它为基础绘制圆形图片。(为啥?就是BitmapShader是从你的画布的左上角开始绘制的,如果直接用长方形的bitmap,绘制出来的圆形图像只能是左/上的那部分,囧…)

那么?该如何进一步优化?能不能把中间那部square bitmap的创建去掉了,这应该能在图片大量加载的时候省下不少开辟内存空间的开销(虽然最后GC还是会回收那部分中间内存,但总觉得不够优雅)。

经过一番查询, BitmapShader是可以通过setLocalMatrix()方法设置一个Matrix来进行矩阵变换的,也就是其实是可以不从原图的左上角开始绘制。说到这里,大家应该都知道如何进行优化了,下面贴出代码,省下了中间的square bitmap的创建,棒棒的。代码已上传gist:codezjx/CircleImageTransformation.java

public class CircleImageTransformation implements Transformation {/*** A unique key for the transformation, used for caching purposes.*/private static final String KEY = "circleImageTransformation";@Overridepublic Bitmap transform(Bitmap source) {int minEdge = Math.min(source.getWidth(), source.getHeight());int dx = (source.getWidth() - minEdge) / 2;int dy = (source.getHeight() - minEdge) / 2;// Init shaderShader shader = new BitmapShader(source, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);Matrix matrix = new Matrix();matrix.setTranslate(-dx, -dy);   // Move the target area to center of the source bitmapshader.setLocalMatrix(matrix);// Init paintPaint paint = new Paint(Paint.ANTI_ALIAS_FLAG);paint.setShader(shader);// Create and draw circle bitmapBitmap output = Bitmap.createBitmap(minEdge, minEdge, source.getConfig());Canvas canvas = new Canvas(output);canvas.drawOval(new RectF(0, 0, minEdge, minEdge), paint);// Recycle the source bitmap, because we already generate a new onesource.recycle();return output;}@Overridepublic String key() {return KEY;}
}

最后需要注意一点:重载的key()函数返回的字符串代表着某个配置参数下的Transformation。什么意思呢?也就是说,如果你自定义的Transformation 的构造函数中有配置参数的话,如第一个RoundedTransformation例子中那样,key()返回的字符串必须包含这些参数,这个key用来做cache的时候会用到。如:

@Override
public String key() {return "rounded(radius=" + radius + ", margin=" + margin + ")";
}

Android中使用Picasso将图片直接转换为圆形相关推荐

  1. Android Glide加载图片时转换为圆形、圆角、毛玻璃等图片效果

     Android Glide加载图片时转换为圆形.圆角.毛玻璃等图片效果 附录1简单介绍了Android开源的图片加载框架.在实际的开发中,虽然Glide解决了快速加载图片的问题,但还有一个问题悬 ...

  2. android图片gif动画效果,android中类似于gif 实现图片的动画效果

    案例:实现gif动画效果,连续播放图片 由于是转载的,也就没必要多说,直接上代码 案例:在android中实现gif动态图片的效果: EarthAnimationActivity.java packa ...

  3. android 图像对比,Android中比较两个图片是否一致的问题

    在Fragment界面中,设置两个图片一致如下: 默认设置图片为: binding.ivArrow.setImageResource(R.drawable.icon_down); 先获取默认图片,再和 ...

  4. Android中实现平铺图片

    转载请标明出处:一片枫叶的专栏 最近开发App,美工设计了一个有锯齿边沿效果的背景图,只给了我一个锯齿,然后需要平铺展示锯齿效果: android中实现平铺图片有两种方式: (1)在drawable中 ...

  5. android添加图片按钮,如何给Android中的按钮添加图片功能

    在layout中建一个my_login.xml文件 代码如下 android:layout_width="fill_parent" android:layout_height=&q ...

  6. Android中显示gif动态图片

    在android中显示一个静态图片比如png jpg等等都很方便,但是如果要显示一个gif 动态图片就需要进行一些处理. 本文是采用自定义view 然后进行重新onDraw方法来实现 首先自定义Vie ...

  7. 在Android中绘制圆角矩形图片

    圆角矩形图片在苹果的产品中很流行,相比于普通的矩形,很多人都喜欢圆角矩形的图片,下面在Android中实现将普通的矩形图片绘制成圆角矩形.        先来看一下普通矩形图片的显示,代码很简单,从r ...

  8. Android中绘制圆角矩形图片及任意形状图片

    转自http://blog.csdn.net/silangquan/article/details/8056583 圆角矩形图片在苹果的产品中很流行,相比于普通的矩形,很多人都喜欢圆角矩形的图片,因为 ...

  9. android matrix 实现点击旋转,Android中利用matrix 控制图片的旋转、缩放、移动

    本文主要讲解利用android中Matrix控制图形的旋转缩放移动,具体参见一下代码: /** * 使用矩阵控制图片移动.缩放.旋转 */ public class CommonImgEffectVi ...

最新文章

  1. Java的多线程问题追根溯源。
  2. 推荐一本书给大家《不懂带人 你就自己做到死》
  3. python 函数递归一次增加一次变量_python基础之函数、返回值,局部变量、全局变量,递归(继续补充不定长参数)...
  4. scheme 学习:pair 和 list
  5. 配置VRRP(虚拟路由器冗余协议)
  6. gho镜像安装器linux,Ghost镜像安装器
  7. 零基础转行自学前端,怎么学习更系统?
  8. 【语音去噪】基于matlab改进谱减法语音去噪【含Matlab源码 569期】
  9. 大学生游戏静态HTML网页作业--美丽中国
  10. java二级大题分值_2017年9月全国计算机等级考试各级别题型分值
  11. 郑厂长系列故事——排兵布阵 状态压缩DP
  12. CPSR SPSR
  13. ssrender例子
  14. 边缘计算的深刻详细解读
  15. 炒菜机器人放食材的顺序_炒菜机器人的制作方法
  16. android常用刷机指令,刷机以及常用命令
  17. 【JLOI2014】松鼠的新家
  18. 小程序黑马优购商城项目讲解
  19. Vue中使用ES6的三点运算符(扩展运算符)报错解决
  20. 安卓 自定义相机,身份证拍照

热门文章

  1. Flowable流程启动源码分析
  2. java 类的方法设计_设计问题:Java类与单方法OK?
  3. 网络安全专业应届生必备的几个实用工具,快收藏
  4. CMOS图像传感器——概述
  5. HTML筑基知识点二
  6. linux 格式化 4k对齐,硬盘WD10EARS在FreeNas的格式化方法,4k对齐的问题
  7. mysql数据库容灾备份软件_mysql 容灾备份
  8. 设计原则—SOLID(LSP)
  9. android电子标签,RFID超高频(UHF)智能柜安卓(ANDRIOD)控制器UKA02
  10. (1)英文分词——波特词干提取算法