图片加载框架之Glide和Picasso
Glide介绍
Glide是一个加载图片的库,作者是bumptech,它是在泰国举行的google 开发者论坛上google为我们介绍的,这个库被广泛的运用在google的开源项目中。
Glide是一个非常成熟的图片加载库,他可以从多个源加载图片,如:网路,本地,Uri等,更重要的是他内部封装了非常好的缓存机制并且在处理图片的时候能保持一个低的内存消耗。
Picasso介绍(毕加索)
picasso是Square公司开源的一个Android图形缓存库,地址http://square.github.io/picasso/,可以实现图片下载和缓存功能。仅仅只需要一行代码就能完全实现图片的异步加载
1.在adapter中需要取消已经不在视野范围的ImageView图片资源的加载,否则会导致图片错位,Picasso已经解决了这个问题。
2.使用复杂的图片压缩转换来尽可能的减少内存消耗
3.自带内存和硬盘二级缓存功能
二者用法类似,根据gihthub上添加依赖库,添加联网权限
区别:
区别一:with的参数
将Activity/Fragment作为with参数的好处:图片加载和Activity/Fragment的生命周期保持一致,比如Pause状态暂停加载,在resume时候重新加载,建议传参的时候给Activity/Fragment给Glide而不是context
区别二:图片质量
Glide默认的bitmap格式为RGB_565
Picasso默认的bitmap格式为ARGB_8888
区别三:加载Gif图片
Glide的一个明显的优点就是它可以加载gif图片,用Picasso加载的gif图片是不会动的
因为Glide被设计成能和Activity/Fragment的生命周期完美的相结合,因此gif动画将随着Activity/Fragment的生命周期自动的开始和停止。
gif的缓存和一般的图片也是一样的,也是第一次加载的时候调整大小,然后缓存。
注意:gif图片将消耗非常多的内存,因此要慎用。
区别四:缓存策略和加载速度
Picasso的缓存是全尺寸的,而Glide的缓存根据ImageView的尺寸相同
将ImageView调整成不同的大小,不管大小如何,Picasso值缓存一个全尺寸的,Picasso则需要在显示前重新调整大小而导致一下延迟.
而Glide不同,它会为每种大小尺寸缓存一下,加载速度比Picasso更快,磁盘策略比Picasso更好,但需要更大的空间来缓存,Glide比Picasso更有利于减少OOM的发生
基本用法
Glide.with(this).load(url).into(imageView);
Picasso.with(this).load(url).into(imageView);
Glide:修改缓存大小、位置、加载图片质量的实现
自定义一个glideConfigModule.java实体类继承GlideModule
import android.content.Context; import com.bumptech.glide.Glide;
import com.bumptech.glide.GlideBuilder;
import com.bumptech.glide.load.DecodeFormat;
import com.bumptech.glide.load.engine.bitmap_recycle.LruBitmapPool;
import com.bumptech.glide.load.engine.cache.InternalCacheDiskCacheFactory;
import com.bumptech.glide.load.engine.cache.LruResourceCache;
import com.bumptech.glide.module.GlideModule; public class GlideConfigModule implements GlideModule {
@Override
public void applyOptions(Context context, GlideBuilder builder) {
// 指定位置在packageName/cache/glide_cache,大小为MAX_CACHE_DISK_SIZE的磁盘缓存
builder.setDiskCache(new InternalCacheDiskCacheFactory(context, "glide_cache", 10*1024*1024));
//指定内存缓存大小 Runtime.getRuntime().maxMemory()运行的最大内存值
builder.setMemoryCache(new LruResourceCache(10*1024*1024));
//全部的内存缓存用来作为图片缓存
builder.setBitmapPool(new LruBitmapPool(10*1024*1024));
//设置图片质量格式,设置和Picasso配置一样
builder.setDecodeFormat(DecodeFormat.PREFER_ARGB_8888);/
} @Override
public void registerComponents(Context context, Glide glide) { }
}
在清单文件中配置
<meta-data
android:name="com.jcf.glidedemo.GlideConfigModule"
android:value="GlideModule"/>
Glide:不为ImageView类型加载的实现
譬如加载的控件类型不是ImageView,是个自定义的布局。或者加载为Background的形式。可以使用SimpleTarget
类型,这里指定他的大小为500*100,加载为背景图片。
.into(new SimpleTarget<GlideDrawable>(500,200) {
@Override
public void onResourceReady(GlideDrawable glideDrawable, GlideAnimation<? super GlideDrawable> glideAnimation) {
tv.setBackground(glideDrawable);
}
});
Picasso自定义截取图片的实现
import android.graphics.Bitmap;
import com.squareup.picasso.Transformation;
public class CropSquareTransformation implements Transformation {
@Override
public Bitmap transform(Bitmap bitmap) {
int size = Math.min(bitmap.getWidth(), bitmap.getHeight());
int x = (bitmap.getWidth() - size) / 2;
int y = (bitmap.getHeight() - size) / 2;
Bitmap result = Bitmap.createBitmap(bitmap, x, y, size, size);
if (result != bitmap) {
bitmap.recycle();
}
return result;
}
@Override
public String key() {
return "square()";
}
}
使用
Picasso.with(this)
.load(url)
.transform(new CropSquareTransformation())
.into(ivPicasso);
二者在开发中用法
Glide.with(this)
.load("https://ss0.bdstatic.com/94oJfD_bAAcT8t7mm9GUKT-xh_/timg?image&quality=100&size=b4000_4000&sec=1483868451&di=2c4c2a41347e49eca30ee3a2276034c0&src=http://file27.mafengwo.net/M00/B2/12/wKgB6lO0ahWAMhL8AAV1yBFJDJw20.jpeg")
.crossFade()
.listener(mRequestListener)//配置监听器
.animate(android.R.anim.slide_in_left) //配置自带淡出淡入动画
//.animate(R.anim.scale) //可设置自定义的动画
.override(100, 100) //为图片重新定义大小
.placeholder(R.mipmap.ic_launcher)//加载中的图片
//.fitCenter() //根据布局大小填充图片,必须和centerCrop一起设置设置fitCenter(),不能再调用override()
//.centerCrop() //图片要填充整个控件,去两边留中间
.error(R.mipmap.ic_launcher)//加载失败的涂料
.priority(Priority.HIGH) //优先级
.into(ivGlide);//加载到控件上
Picasso.with(this)
// .load("https://ss0.bdstatic.com/94oJfD_bAAcT8t7mm9GUKT-xh_/timg?image&quality=100&size=b4000_4000&sec=1483868451&di=2c4c2a41347e49eca30ee3a2276034c0&src=http://file27.mafengwo.net/M00/B2/12/wKgB6lO0ahWAMhL8AAV1yBFJDJw20.jpeg")
.load("https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1483885293073&di=4d6626505c2c3ca8a9e7f580c08884a8&imgtype=0&src=http%3A%2F%2Fimg5.duitang.com%2Fuploads%2Fitem%2F201510%2F30%2F20151030165654_fyUJW.thumb.700_0.gif")
.error(R.mipmap.ic_launcher)
//.fit() //控件不能设置成wrap_content,也就是必须有大小才行,fit()才让图片的宽高等于控件的宽高,设置fit(),不能再调用resize()
//.centerCrop() //图片要填充整个控件,去两边留中间
.resize(100,100) ////为图片重新定义大小
.placeholder(R.mipmap.ic_launcher)
.priority(Picasso.Priority.HIGH)
.into(ivPicasso);
}
private RequestListener<String, GlideDrawable> mRequestListener = new RequestListener<String, GlideDrawable>() {
@Override
public boolean onException(Exception e, String model, Target<GlideDrawable> target, boolean isFirstResource) {
//显示错误信息
Log.w(TAG, "onException: ", e);
//打印请求URL
Log.d(TAG, "onException: " + model);
//打印请求是否还在进行
Log.d(TAG, "onException: " + target.getRequest().isRunning());
return false;
} @Override
public boolean onResourceReady(GlideDrawable resource, String model, Target<GlideDrawable> target, boolean isFromMemoryCache, boolean isFirstResource) {
if (isFromMemoryCache) {
//如果是从缓存加载,设置动画效果
ivGlide.setAnimation(AnimationUtils.loadAnimation(MainActivity.this, R.anim.scale));
}
//返回true表示拦截不再传递,false表示事件会传递下去
return false; }
};
Picasso圆形图片的实现
// 自定义Transformation
Transformation transform = new Transformation() {
@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;
} @Override
public String key() {
return "circle";
}
};
Picasso
.with(this)// 指定Context
.load(URL_IMG2) //指定图片URL
.transform(transform) // 指定图片转换器
.into(imageView); // 指定显示图片的ImageView
Picasso圆形图片的实现
class RoundedTransformation implements com.squareup.picasso.Transformation {
private final int radius;
private final int margin; // dp // radius is corner radii in dp
// margin is the board in dp
public RoundedTransformation(final int radius, final int margin) {
this.radius = radius;
this.margin = margin;
} @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(), Bitmap.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;
} @Override
public String key() {
return "rounded(radius=" + radius + ", margin=" + margin + ")";
}
}
Picasso
.with(this)// 指定Context
.load(URL_IMG2) //指定图片URL
.transform(new RoundedTransformation(360,0)) // 指定图片转换器
.into(imageView); // 指定显示图片的ImageView
Glide显示圆形图片的实现
class GlideCircleTransform extends BitmapTransformation {
public GlideCircleTransform(Context context) {
super(context);
} @Override
protected Bitmap transform(BitmapPool pool, Bitmap toTransform, int outWidth, int outHeight) {
return circleCrop(pool, toTransform);
} private Bitmap circleCrop(BitmapPool pool, Bitmap source) {
if (source == null) return null; int size = Math.min(source.getWidth(), source.getHeight());
int x = (source.getWidth() - size) / 2;
int y = (source.getHeight() - size) / 2; // TODO this could be acquired from the pool too
Bitmap squared = Bitmap.createBitmap(source, x, y, size, size); Bitmap result = pool.get(size, size, Bitmap.Config.ARGB_8888);
if (result == null) {
result = Bitmap.createBitmap(size, size, Bitmap.Config.ARGB_8888);
} Canvas canvas = new Canvas(result);
Paint paint = new Paint();
paint.setShader(new BitmapShader(squared, BitmapShader.TileMode.CLAMP, BitmapShader.TileMode.CLAMP));
paint.setAntiAlias(true);
float r = size / 2f;
canvas.drawCircle(r, r, r, paint);
return result;
} @Override
public String getId() {
return getClass().getName();
}
} Glide
.with(this) // 指定Context
.load(URL_GIF)// 指定图片的URL
.transform(new GlideCircleTransform(this)) // 指定自定义图片样式
.into(imageView);//指定显示图片的ImageView
Glide显示圆角图片的实现
class GlideRoundTransform extends BitmapTransformation { private float radius = 0f; public GlideRoundTransform(Context context) {
this(context, 4);
} public GlideRoundTransform(Context context, int dp) {
super(context);
this.radius = Resources.getSystem().getDisplayMetrics().density * dp;
} @Override protected Bitmap transform(BitmapPool pool, Bitmap toTransform, int outWidth, int outHeight) {
return roundCrop(pool, toTransform);
} private Bitmap roundCrop(BitmapPool pool, Bitmap source) {
if (source == null) return null; Bitmap result = pool.get(source.getWidth(), source.getHeight(), Bitmap.Config.ARGB_8888);
if (result == null) {
result = Bitmap.createBitmap(source.getWidth(), source.getHeight(), Bitmap.Config.ARGB_8888);
} Canvas canvas = new Canvas(result);
Paint paint = new Paint();
paint.setShader(new BitmapShader(source, BitmapShader.TileMode.CLAMP, BitmapShader.TileMode.CLAMP));
paint.setAntiAlias(true);
RectF rectF = new RectF(0f, 0f, source.getWidth(), source.getHeight());
canvas.drawRoundRect(rectF, radius, radius, paint);
return result;
} @Override public String getId() {
return getClass().getName() + Math.round(radius);
}
}
Glide
.with(this) // 指定Context
.load(URL_GIF)// 指定图片的URL
.transform(new GlideRoundTransform(this,30)) // 指定自定义图片样式
.into(imageView);//指定显示图片的ImageView
图片加载框架之Glide和Picasso的更多相关文章
- android-------非常好的图片加载框架和缓存库(Picasso)
Picasso是Square公司开源的一个Android图形缓存库, 可以实现图片加载(本地和网络)和缓存功能. 地址:http://square.github.io/picasso/ jar包下载: ...
- Android 三大图片加载框架的对比——ImageLoader,Picasso,Glide
一.ImageLaoder介绍 << Universal ImageLoader 是很早开源的图片缓存,在早期被很多应用使用 多线程下载图片,图片可以来源于网络,文件系统,项目文件夹ass ...
- 安卓图片加载框架之Glide框架
Glide框架加载有两种,第一,是加载图片,第二是加载布局背景.首先我来说说第一种情况加载图片. Glide.with(getActivity()).load(lists.get(position). ...
- 主流图片加载框架 ImageLoader、Glide、Picasso、Fresco 对比
图片缓存库主页: Glidehttps://github.com/bumptech/glide fresco - An Android library for managing images and ...
- Android 图片加载框架 Glide 的用法
https://github.com/bumptech/glide Android图片加载框架最全解析(一),Glide的基本用法http://blog.csdn.net/guolin_blog/ar ...
- Android图片加载框架最全解析(八),带你全面了解Glide 4的用法
本篇将是我们这个Glide系列的最后一篇文章. 其实在写这个系列第一篇文章的时候,Glide就推出4.0.0的RC版了.那个时候因为我一直研究的都是Glide 3.7.0版本,再加上RC版本还不太稳定 ...
- Android图片加载框架最全解析(六),探究Glide的自定义模块功能
不知不觉中,我们的Glide系列教程已经到了第六篇了,距离第一篇Glide的基本用法发布已经过去了半年的时间.在这半年中,我们通过用法讲解和源码分析配合学习的方式,将Glide的方方面面都研究了个遍, ...
- Android图片加载框架最全解析(一),Glide的基本用法
现在Android上的图片加载框架非常成熟,从最早的老牌图片加载框架UniversalImageLoader,到后来Google推出的Volley,再到后来的新兴军Glide和Picasso,当然还有 ...
- Android之Glide(非常好用的图片加载框架)
谷歌开发者论坛上,谷歌为我们介绍了一个名叫 Glide 的图片加载库,作者是bumptech. Glide是一种快速.高效的开源媒体管理和Android的包裹mediadecoding图像加载框架,内 ...
随机推荐
- 6.Shell 计划任务服务程序
计划任务服务程序 经验丰富的系统运维工程师可以使得Linux在无需人为介入的情况下,在指定的时间段自动启用或停止某些服务或命令,从而实现运维的自动化. 如何设置服务器的计划任务服务,把周期性.规律性的 ...
- Webpack编译提示内存溢出解决方案
在项目开发中,随着业务需求的复杂项目随之增大,再加上同一个文件被引用次数过于频繁在开发编译或者上线打包时经常会出现如下错误: 这个报错的意思就是Node内存不足所导致的,我们都知道 Node 是基于V ...
- Diagonal Walking v.2 CodeForces - 1036B (思维,贪心)
Diagonal Walking v.2 CodeForces - 1036B Mikhail walks on a Cartesian plane. He starts at the point ( ...
- 搭建单机版伪分布zookeeper集群
一.下载zookeeper http://mirrors.shu.edu.cn/apache/zookeeper/stable/ 我下载的是3.4.13版本 上传到liunx虚拟机上,解压 再复制出2 ...
- log1p和expm1
在数据预处理时首先可以对偏度比较大的数据用log1p函数进行转化,使其更加服从高斯分布,此步处理可能会使我们后续的分类结果得到一个更好的结果:平滑处理很容易被忽略掉,导致模型的结果总是达不到一定的标准 ...
- nginx 访问控制模块
截图,代码截屏均引用自慕课网nginx相关教学视频 基于用户的访问控制模块 http_access_module 基于用户登录信任的模块 http_access_module 参数示意:address ...
- Linux 常用命令备忘
安装wget 方便联网下载: centos : sudo yum -y install wget 安装vim : yum -y install vim* set nu ...
- Remote API(RAPI)之 文件管理
RAPI库由一组函数组成,这些函数可用于通过桌面应用程序管理设备,包括设备的目录文件.设备的注册表和系统信息. RAPI提供了一组文件管理方法 CeCopyFile:复制文件 CeCreateDire ...
- PC监听鼠标和键盘事件,定时无响应退出
直接上代码: window.onload = function () { initScreenSaver(); } //0912 add function ScreenSaver(settings){ ...
- yii框架学习(安装)
安装yii: 在本地安装前, 要确保PHP配置了环境变量, 通过cmd输入PHP -v 即可检测. 能看到PHP版本号, 则OK. PHP不是内部命令,则需要添加PHP环境变量. 使用compos ...