Android中使用Picasso将图片直接转换为圆形
圆形头像现在很流行了,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将图片直接转换为圆形相关推荐
- Android Glide加载图片时转换为圆形、圆角、毛玻璃等图片效果
Android Glide加载图片时转换为圆形.圆角.毛玻璃等图片效果 附录1简单介绍了Android开源的图片加载框架.在实际的开发中,虽然Glide解决了快速加载图片的问题,但还有一个问题悬 ...
- android图片gif动画效果,android中类似于gif 实现图片的动画效果
案例:实现gif动画效果,连续播放图片 由于是转载的,也就没必要多说,直接上代码 案例:在android中实现gif动态图片的效果: EarthAnimationActivity.java packa ...
- android 图像对比,Android中比较两个图片是否一致的问题
在Fragment界面中,设置两个图片一致如下: 默认设置图片为: binding.ivArrow.setImageResource(R.drawable.icon_down); 先获取默认图片,再和 ...
- Android中实现平铺图片
转载请标明出处:一片枫叶的专栏 最近开发App,美工设计了一个有锯齿边沿效果的背景图,只给了我一个锯齿,然后需要平铺展示锯齿效果: android中实现平铺图片有两种方式: (1)在drawable中 ...
- android添加图片按钮,如何给Android中的按钮添加图片功能
在layout中建一个my_login.xml文件 代码如下 android:layout_width="fill_parent" android:layout_height=&q ...
- Android中显示gif动态图片
在android中显示一个静态图片比如png jpg等等都很方便,但是如果要显示一个gif 动态图片就需要进行一些处理. 本文是采用自定义view 然后进行重新onDraw方法来实现 首先自定义Vie ...
- 在Android中绘制圆角矩形图片
圆角矩形图片在苹果的产品中很流行,相比于普通的矩形,很多人都喜欢圆角矩形的图片,下面在Android中实现将普通的矩形图片绘制成圆角矩形. 先来看一下普通矩形图片的显示,代码很简单,从r ...
- Android中绘制圆角矩形图片及任意形状图片
转自http://blog.csdn.net/silangquan/article/details/8056583 圆角矩形图片在苹果的产品中很流行,相比于普通的矩形,很多人都喜欢圆角矩形的图片,因为 ...
- android matrix 实现点击旋转,Android中利用matrix 控制图片的旋转、缩放、移动
本文主要讲解利用android中Matrix控制图形的旋转缩放移动,具体参见一下代码: /** * 使用矩阵控制图片移动.缩放.旋转 */ public class CommonImgEffectVi ...
最新文章
- Java的多线程问题追根溯源。
- 推荐一本书给大家《不懂带人 你就自己做到死》
- python 函数递归一次增加一次变量_python基础之函数、返回值,局部变量、全局变量,递归(继续补充不定长参数)...
- scheme 学习:pair 和 list
- 配置VRRP(虚拟路由器冗余协议)
- gho镜像安装器linux,Ghost镜像安装器
- 零基础转行自学前端,怎么学习更系统?
- 【语音去噪】基于matlab改进谱减法语音去噪【含Matlab源码 569期】
- 大学生游戏静态HTML网页作业--美丽中国
- java二级大题分值_2017年9月全国计算机等级考试各级别题型分值
- 郑厂长系列故事——排兵布阵 状态压缩DP
- CPSR SPSR
- ssrender例子
- 边缘计算的深刻详细解读
- 炒菜机器人放食材的顺序_炒菜机器人的制作方法
- android常用刷机指令,刷机以及常用命令
- 【JLOI2014】松鼠的新家
- 小程序黑马优购商城项目讲解
- Vue中使用ES6的三点运算符(扩展运算符)报错解决
- 安卓 自定义相机,身份证拍照