1.简介
- 1)google亲儿子,Glide和Picasso有90%的相似度,准确的说,就是Picasso的克隆版本。但是在细节上还是有不少区别的。
- 2)导入库,Picasso和Glide都在jcenter上。在项目中添加依赖非常简单:参考官网
Picasso:
dependencies {
compile ‘com.squareup.picasso:picasso:2.5.1’
}
Glide //Glide需要依赖Support Library v4,别忘了。其实Support Library v4已经是应用程序的标配了,这不是什么问题。
dependencies {
compile ‘com.github.bumptech.glide:glide:3.5.2’
compile ‘com.android.support:support-v4:22.0.0’
}
3.基础
- 1)就如我所说的Glide和Picasso非常相似,Glide加载图片的方法和Picasso如出一辙。
Picasso
Picasso.with(context)
.load("http://inthecheesefactory.com/uploads/source/glidepicasso/cover.jpg")
.into(ivImg);
Glide
Glide.with(context) .load("http://inthecheesefactory.com/uploads/source/glidepicasso/cover.jpg")
.into(ivImg);
虽然两者看起来一样,但是Glide更易用,因为Glide的with方法不光接受Context,还接受Activity 和 Fragment,Context会自动的从他们获取。
同 时将Activity/Fragment作为with()参数的好处是:图片加载会和Activity/Fragment的生命周期保持一致,比如 Paused状态在暂停加载,在Resumed的时候又自动重新加载。所以我建议传参的时候传递Activity 和 Fragment给Glide,而不是Context。
4.默认Bitmap格式是RGB_565
1)下面是加载图片时和Picasso的比较(1920x1080 像素的图片加载到768x432的ImageView中)
2)可以看到Glide加载的图片质量要差于Picasso(ps:我看不出来哈),为什么?这是因为Glide默认的Bitmap格式是RGB_565 ,比ARGB_8888格式的内存开销要小一半。下面是Picasso在ARGB8888下与Glide在RGB565下的内存开销图(应用自身占用了8m,因此以8为基准线比较):
3)如果你对默认的RGB_565效果还比较满意,可以不做任何事,但是如果你觉得难以接受,可以创建一个新的GlideModule将Bitmap格式转换到ARGB_8888:
- 4)步骤一
public class GlideConfiguration implements GlideModule {
@Override
public void applyOptions(Context context, GlideBuilder builder) {
// Apply options to the builder here.
builder.setDecodeFormat(DecodeFormat.PREFER_ARGB_8888);
}
@Override
public void registerComponents(Context context, Glide glide) {
// register ModelLoaders here.
}
}
步骤二:同时在AndroidManifest.xml中将GlideModule定义为meta-data
<meta-data android:name="com.inthecheesefactory.lab.glidepicasso.GlideConfiguration"
android:value="GlideModule"/>
5)我们再来看看内存开销图,这次貌似Glide花费了两倍于上次的内存,但是Picasso的内存开销仍然远大于Glide。
/*原因在于Picasso是加载了全尺寸的图片到内存,然后让GPU来实时重绘大小。而Glide加载的大小和ImageView的大小是一致的,因此更小。当然,Picasso也可以指定加载的图片大小的:*/
Picasso.with(this)
.load("http://nuuneoi.com/uploads/source/playstore/cover.jpg")
.resize(768, 432)
.into(ivImgPicasso);
/*但是问题在于你需要主动计算ImageView的大小,或者说你的ImageView大小是具体的值(而不是wrap_content),你也可以这样:*/
Picasso.with(this)
.load("http://nuuneoi.com/uploads/source/playstore/cover.jpg")
.fit()
.centerCrop()
.into(ivImgPicasso);
//现在Picasso的内存开销就和Glide差不多了。
总结:虽然内存开销差距不到,但是在这个问题上Glide完胜Picasso。因为Glide可以自动计算出任意情况下的ImageView大小。
- 5.Image质量的细节
这是将ImageView还原到真实大小时的比较。
你可以看到,Glide加载的图片没有Picasso那么平滑,我还没有找到一个可以直观改变图片大小调整算法的方法。但是这并不算什么坏事,因为很难察觉。
- 6.磁盘缓存
1)Picasso和Glide在磁盘缓存策略上有很大的不同。Picasso缓存的是全尺寸的,而Glide缓存的是跟ImageView尺寸相同的。
/*上面提到的平滑度的问题依然存在,而且如果加载的是RGB565图片,那么缓存中的图片也是RGB565。
我尝试将ImageView调整成不同大小,但不管大小如何Picasso只缓存一个全尺寸的。Glide则不同,它会为每种大小的ImageView缓存 一次。尽管一张图片已经缓存了一次,但是假如你要在另外一个地方再次以不同尺寸显示,需要重新下载,调整成新尺寸的大小,然后将这个尺寸的也缓存起来。
具体说来就是:假如在第一个页面有一个200x200的ImageView,在第二个页面有一个100x100的ImageView,这两个ImageView本来是要显示同一张图片,却需要下载两次。
不过,你可以改变这种行为,让Glide既缓存全尺寸又缓存其他尺寸:*/
Glide.with(context)
Glide.with(this)
.load("http://nuuneoi.com/uploads/source/playstore/cover.jpg")
.diskCacheStrategy(DiskCacheStrategy.ALL)
.into(ivImgGlide);
/*Glide的这种方式优点是加载显示非常快。而Picasso的方式则因为需要在显示之前重新调整大小而导致一些延迟,即便你添加了这段代码来让其立即显示:*/
Picasso.noFade();
- 7.特性
- 1)Picasso和Glide各有所长,你根据自己的需求选择合适的,你可以做到几乎和Picasso一样多的事情,代码也几乎一样,对我而言,我更喜欢Glide,因为它远比Picasso快,虽然需要更大的空间来缓存。
- 2)Image Resizing 重新计算图片大小
// Picasso
.resize(300, 200);
// Glide
.override(300, 200);
3)Center Cropping
// Picasso
.centerCrop();
// Glide
.centerCrop();
4)Transforming
// Picasso
.transform(new CircleTransform())
// Glide
.transform(new CircleTransform(context))
5)设置占位图或者加载错误图:
/ Picasso
.placeholder(R.drawable.placeholder)
.error(R.drawable.imagenotfound)
// Glide
.placeholder(R.drawable.placeholder)
.error(R.drawable.imagenotfound)
8.有什么Glide可以做而Picasso 做不到?
- 1)Glide可以加在GIF动态图,而Picasso不能。
- 2)同时因为Glide和Activity/Fragment的生命周期是一致的,因此gif的动画也会自动的随着Activity/Fragment的状态暂停、重放。Glide 的缓存在gif这里也是一样,调整大小然后缓存,但是从我的一次测试结果来看Glide 动画会消费太多的内存,因此谨慎使用,除了gif动画之外,Glide还可以将任何的本地视频解码成一张静态图片。,还有一个特性是你可以配置图片显示的动画,而Picasso只有一种动画:fading in。,最后一个是可以使用thumbnail()产生一个你所加载图片的thumbnail。,其实还有一些特性,不过不是非常重要,比如将图像转换成字节数组等。,有许多可以配置的选项,比如大小,缓存的磁盘位置,最大缓存空间,位图格式等等。可以在这个页面查看这些配置 Configuration 。
9.库的大小
//必须指出,对于DEX文件65535个方法的限制来说,2678是一个相当大的数字了。建议在使用Glide的时候开启ProGuard。
10.总结
- 1)Glide和Picasso都是非常完美的库。Glide加载图像以及磁盘缓存的方式都要优于Picasso,速度更快,并且Glide更有利于减少OutOfMemoryError的发生,GIF动画是Glide的杀手锏。不过Picasso的图片质量更高。你更喜欢哪个呢?
- 2)建议是使用Glide,但需要将Bitmap格式换成 ARGB_8888、并能让Glide缓存同时缓存全尺寸和改变尺寸两种。
12.图片加载的位置:
- 1)在getView中加载
- 2)在构造方法中设置,在getView中加载设置显示控件
- 1)在getView中加载
- 13.基础语法第一次:从一个 URL 中加载图片
- 1)就像 Picasso, Glide 库是使用流接口(fluent interface)。对一个完整的功能请求,Glide 建造者要求最少有三个参数。
// 第一步:需要一个ImageView控件
ImageView targetImageView = (ImageView) findViewById(R.id.imageView);
// 第二步:需要一个图片地址,String即可,会被Glide自动加载
String internetUrl = "http://i.imgur.com/DvpvklR.png";
Glide
.with(context) //with(Context context) 对于很多 Android API 调用,Context 是必须的。
.load(internetUrl) //lload(String imageUrl) 指定加载的图片路径,参数以一个字符串的形式来表示一个网络图片的 URL
.into(targetImageView);//into就是放到哪个控件上来显示,into(ImageView targetImageView) 下载后的图片会被显示到对应的 ImageView 中。
//如果图片的 URL 存在并且你的 ImageView 是可见的,你会在几秒后看到图片。万一图片不存在,Glide 会返回一个错误的回调
- 2)从不同的图片来源中加载图片,说白了就是load()参数的来源不用造成的
- 3)从资源中加载:int resourceId = R.mipmap.ic_launcher; load(resourceId)
- 4)从文件中加载:File file = new File(XXX);load(file)
- 5)从 Uri 中加载:Uri uri = Uri.parse(XXX);load(uri)
public static final String ANDROID_RESOURCE = "android.resource://";
public static final String FOREWARD_SLASH = "/";
private static Uri resourceIdToUri(Context context, int resourceId) {
return Uri.parse(ANDROID_RESOURCE + context.getPackageName() + FOREWARD_SLASH + resourceId);
}
Uri uri = resourceIdToUri(context, R.mipmap.future_studio_launcher);
6)在listView的adapter 中实现
- 1)步骤一:从服务器中获取的图片地址存放到一个数组中
- 2)步骤二:要一个 activity,它创建一个 adapter 并设置给一个 ListView。
- 3)步骤三:部署adapter 的布局文件。也就是ListView 的 item 的布局文件
- 4)步骤四:为 ListView 实现一个 ArrayAdapter,在其getView()回调方法中调用Glide方法,Glide框架会自动去请求图片来加载
7)当加载图片时,Glide 使用3个来源:内存,磁盘和网络(从最快到最慢排序)。再说一次,这里你不需要做任何事情。Glide 帮你隐藏了所有复杂的情况,同时为你创建了一个智能的缓存大小。
8)添加占位符 【占位图片】
- 1)一个预期的行为是一个APP 去显示一个占位符直到这张图片加载处理完成。
- 2)具体实现:只需要调用 .placeHolder() 用一个 drawable(resource) 引用 【网络请求之前的图片显示】
- 3)而发送网络请求后出现异常,则Glide 给我们一个选项去获取一个错误的回调并采取合适的行动,调用.error()
- 4)如果你定义的 load() 值的图片不能被加载出来,Glide 会显示error()中的图片,但error()接受的参数只能是已经初始化的 drawable 对象或者指明它的资源
- 5)调用.crossFade()还有另外重载方法 .crossFade(int duration)。如果你想要去减慢(或加快)动画,随时可以传一个毫秒的时间给这个方法。动画默认的持续时间是 300毫秒,淡入淡出动画效果会使改变更加平滑,当前版本3.6.1)默认激活,建议添加。
- 6)任何参数的组合都是可能的
9)重新调整图片大小
- 1)Glide 有更加高效的内存管理。Glide 自动限制了图片的尺寸在缓存和内存中,并给到 ImageView 需要的尺寸。Picasso 也有这样的能力,但需要调用 fit() 方法。对于 Glide,如果图片不会自动适配到 ImageView,调用 override(horizontalSize, verticalSize) 。这将在图片显示到 ImageView之前重新改变图片大小。
- 2) .override(600, 200) // resizes the image to these dimensions (in pixel). does not respect aspect ratio
10) 缩放图像
- 1)CenterCrop()是一个裁剪技术,即缩放图像让它填充到 ImageView 界限内并且侧键额外的部分。ImageView 可能会完全填充,但图像可能不会完整显示。
- 2) .centerCrop() // this cropping technique scales the image so that it fills the requested bounds and then crops the extra.
- 3)fitCenter() 是裁剪技术,即缩放图像让图像都测量出来等于或小于 ImageView 的边界范围。该图像将会完全显示,但可能不会填满整个 ImageView。
从不同的数据源加载图片
http://www.jianshu.com/p/31c82862ef19
如何调试Glide加载图片?
http://www.jcodecraeer.com/a/anzhuokaifa/androidkaifa/2015/1201/3737.html
加载网络图片但没URL?不要紧,通过ModelLoader,让Glide直接加载任何奇葩数据源
http://www.jcodecraeer.com/a/anzhuokaifa/androidkaifa/2015/0927/3521.html
使用Glide优化图片加载的
http://www.jcodecraeer.com/a/anzhuokaifa/androidkaifa/2015/0728/3228.html
ImageView的scaleType设置不当,导致使用Glide时出现OOM
http://www.jcodecraeer.com/a/anzhuokaifa/androidkaifa/2015/0606/3002.html
支持gif播放,转化为bitmap,以及支持类型检查
Videos/”>http://mrfu.me/2016/02/27/Glide_Displaying_Gifs&_Videos/
默认是将所有的图片资源放到内部缓存中,所以如果图片量很大,就不应这样skipMemoryCache
http://mrfu.me/2016/02/27/Glide_Caching_Basics/
图片加载优先级设置
http://mrfu.me/2016/02/27/Glide_Request_Priorities/
图片加载框架的对比选择
http://stackoverflow.com/questions/29363321/picasso-v-s-imageloader-v-s-fresco-vs-glide
框架学习的正确的逻辑
1.先看几篇原理应用blog
1.查看demo,效果,模仿。就在demo上直接修改
2.先学会用
3.再写小demo,整合到项目中
4.自己用熟后,再来深入解析源码
5.造轮子