During the inauguration of Google Developer Summit Thailand, Google introduced to us an image loader library for android developed by bumptech called Glide as a library recommended by Google. It will be used in many Google open source projects to date, including the official application of Google I/O 2014.
It successfully got me interested. I spent the whole night playing around with it and decided to share my experience in this blog post. To start with I have to say it is almost 90% similar to Picasso. Only more precise, I thought it was something cloned from Picasso.
Anyway, it's quite different in detail. You can learn it here or experiment by yourself.
1. Import to Project
Import Picasso and Glide via jcenter (gradle). It's simple, just put the dependency source like this.
Picasso
dependencies {
compile 'com.squareup.picasso:picasso:2.5.1'
}
Glide
dependencies {
compile 'com.github.bumptech.glide:glide:3.5.2'
compile 'com.android.support:support-v4:22.0.0'
}
However, Glide also requires Android Support Library v4, so don't forget to import support-v4 into your project, but it doesn't matter if your Android Studio is the latest version, because basically for the current generation it is automatically added when a new project is created.
2. Basic Usage
As I said, Glide is similar to picasso. The way to load images via url to ImageView with Glide is almost the same as 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);
Even though it looks pretty much the same, in detail Glide is much better designed since with accepts not only context but also Activity and Fragment. Context will automatically extract whatever you throw at it from those things.
The brilliant benefit of passing Activity/Fragment to Glide is that image loading will be integrated with Activity/Fragment lifecycle for example; image loading pause is applied in paused state and will automatically resume in resumed state. So I recommend you to pass Activity or Fragment to Glide, not just a context if possible.
3. RGB_565 is the Default Bitmap Format
This is a comparison between Glide vs Picasso image loading. (1920x1080 pixels image loaded into 768x432 pixels ImageView).
You can see that the image loaded by Glide has worse quality compared to Picasso. Why? Because Glide's default bitmap format is set to RGB_565 because it only consumes 50% of memory compared to ARGB_8888.
Here is a graph of memory consumption between Picasso on ARGB8888 and Glide on RGB565. (this includes the Application Base which consumes around 8MB).
You don’t need to do anything if you are satisfied with the image quality. But if you think it is unacceptable or not good enough for you, you can change the Bitmap Format to ARGB_8888 by creating a new class extending from GlideModule like this.
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.
}
}
And then define it as meta-data inside AndroidManifest.xml
<meta-data android:name="com.inthecheesefactory.lab.glidepicasso.GlideConfiguration"
android:value="GlideModule"/>
Looks much better now!
Let's take a look at the memory consumption graph once again. It seems that even though Glide consumes almost 2 times of what it used to, Picasso still consumes more memory footprint than Glide.
The reason is that Picasso loads the full size image (1920x1080 pixels) into memory and lets the GPU do the realtime resizing while drawing. While Glide loads the exact size of the ImageView (768x432 pixels) into memory which is a best practice. Anyway you can change the behavior of Picasso to do the same with the resize() command:
Picasso.with(this)
.load("http://nuuneoi.com/uploads/source/playstore/cover.jpg")
.resize(768, 432)
.into(ivImgPicasso);
But the problem is you need to calculate the size of the ImageView manually. Or if your ImageView has the right size (not set to wrap_content), you can do it like this.
Picasso.with(this)
.load("http://nuuneoi.com/uploads/source/playstore/cover.jpg")
.fit()
.centerCrop()
.into(ivImgPicasso);
The memory consumption graphs are now finally almost the same!
Even though the memory consumption is quite the same but I must say that Glide beats Picasso in terms of functionality of this part as it can calculate the size of ImageView automatically in every case.
4. Image Quality Details
This is the result when I try to enlarge the ImageView to its actual size.
It can be seen that the image loaded by Glide has some rough pixels and is not as smooth as Picasso's image. And until now, I still can't find a direct way to change the image resizing algorithm.
But if you ask me is it bad? I would say that it is not that noticeable in real usage. The quality is acceptable but you just need to set Bitmap Format to ARGB_8888, that's all.
5. Disk Caching
The concept of Picasso and Glide's default disk cache is very different. From the experiment, the same Full HD image is loaded into ImageView. When I checked the cache folder, it appears that Glide caches the ImageView size (768x432 pixels) while Picasso records the full size cache (1920x1080 pixels).
And yes, the hard pixels explained above are also there. Also, if an image is loaded in RGB565 mode, the cached image will also be in RGB565. When I tried to adjust the ImageView to different sizes. The result is that no matter what the size is, Picasso will only cache one size of the image, the full size. Glide acts differently, it caches a separate file for each ImageView size. Even though an image has been loaded once but if you need to load another size of the same image, it has to be downloaded once again before being resized to the right resolution and then cached.
To be clearer, if there is an ImageView on the first page with dimensions of 200x200 pixels and on the second page with 100x100 pixels, while the image you want to display is the same, then you have to download the same image twice.
Basically you can customize its behavior by letting Glide cache full size images then resize them with this command.
Glide.with(this)
.load("http://nuuneoi.com/uploads/source/playstore/cover.jpg")
.diskCacheStrategy(DiskCacheStrategy.ALL)
.into(ivImgGlide);
The next time an image is requested to be displayed on any ImageView, the full size image will be loaded from the cache, resized and then cached.
The advantage of the Glide method is that the image can be loaded and displayed very quickly. While the Picasso method causes a loading delay because it needs to be resized first before being set to the ImageView even you add this command to make it display immediately.
//Picasso
.noFade();
There are some trade-offs between Picasso and Glide disk caching methods. You can choose the method that best suits your application needs. For me, I prefer Glide over Picasso because it is much faster even though it requires more space to store images.
6. Features
You can do almost all the same things that Picasso can do with the same coding style for example.
Image Resizing
// Picasso
.resize(300, 200);
// Glide
.override(300, 200);
Center Cropping
// Picasso
.centerCrop();
// Glide
.centerCrop();
Transforming
// Picasso
.transform(new CircleTransform())
// Glide
.transform(new CircleTransform(context))
Setting the Placeholder and Error image
// Picasso
.placeholder(R.drawable.placeholder)
.error(R.drawable.imagenotfound)
// Glide
.placeholder(R.drawable.placeholder)
.error(R.drawable.imagenotfound)
As I said, if you are used to Picasso, moving to Glide is like chewing gum for you , of course it's normal without any problems at all.
7. What does Glide have that Picasso doesn't?
The ability to load animated GIFs into ImageViews is probably Glide's most interesting feature. And yes, you can't do that with Picasso.
And because Glide is designed to work perfectly with the Activity/Fragment lifecycle so animations will automatically pause and resume along with the Activity/Fragment state.
Glide's cache method is still the same, it is resized first and then cached.
The bottom line is that my experiment found that GIF Animation consumes quite a lot of memory. Please use it wisely.
In addition to loading Animated GIFs, Glide can also decode any local video file into still images.
Lastly if you can create a thumbnail file from the image you uploaded then simply use thumbnail().
There are actually some other features you can play around with but most of them are not that important for general use e.g. transcoding images to Byte Array, etc.
8. Configuration
You can customize so many configurations for example, disk cache size and location, maximum memory cache limit, Bitmap Format and many more. You can read more about this on the Configuration page .
9. Library's size
The size of Picasso (v2.5.1) is around 118KB while Glide (v3.5.2) is around 430KB.
However, a 312KB difference may not be that significant.
The counts of the Picasso and Glide methods are 840 and 2678 respectively.
I have to say 2678 is quite a lot for the 65535 method limit of Android DEX files. ProGuard is recommended to be turned on if you choose Glide. (And you should keep it on for production releases).
10. Conclusion
Glide and Picasso are not perfect. Glide’s way of loading images into memory and caching them is better than Picasso which lets images load much faster. Moreover, it also helps prevent the app from the popular OutOfMemoryError. Animated GIF loading is a killer feature provided by Glide. However Picasso is better in terms of rendering images with better quality than Glide.
Which one do I prefer? Although I used Picasso for a very long time, I have to admit that now I prefer Glide. But I would recommend you to change the Bitmap Format to ARGB_8888 and let Glide cache the full size image and resize it first. The rest will do its job!