Imagine a bacon-wrapped Ferrari. Still not better than our free technical reports.
See all our reports

Android image loading – Picasso!

WEBINAR ALERT! If you’re an Android dev and you’re free on September 8th, join us for a very special webinar in partnership with Genymotion – Your Secret Weapons for Faster Android Development: JRebel For Android and Genymotion Emulator.



I wrote my first Android application about 5 years ago, using Eclipse, Ant and loads of old school stuff — no fragments, barely any 3rd party libraries to choose from. I’ve since moved to Android Studio and Gradle, but it has been a year and a half since I’ve sat down and actually written something from scratch to the end. Nowadays, I’m the product manager for the JRebel for Android tool, by ZeroTurnaround, that enables you to reload your application code on your Android device or any emulator without needing to repackage or reinstall the app — you know, those things that take an annoyingly long amount of time. I’d be delighted if you tried it and would gladly hear your feedback on how it improves your productivity as an Android developer.

Having said that I’m still involved with application development on Android and I have a pet project I want to implement, but first I’ve been lurking around the scene to understand what’s hip. I know that I will have to load images, do network requests, cache some data – pretty common stuff I’d say. Today I’m picking my image loading library!

So what’s on the table?

A bit of Googling around made me realise I have 3 options – Picasso, Glide and Fresco. While Picasso and Glide are really similar in their APIs, they still have their differences. Most notably Glide supports .gif files. Although, it’s nice to know that animated images are supported, it is not one of my requirements right now. My main requirements for the library are:

  • Simple API – should be easily wrappable behind an interface so I can replace it anytime
  • Easy to manipulate the images: rotate, scale, blur, mirror and so on
  • Caching – store the images on the device not pulling more data than needed

In this post I’m looking at Picasso, the image loading library by Square, since I know well that their open source tools usually are rock solid and quite easy and pleasant to use. I’m going to report my experience with it on the topics above: simplicity of the API, image manipulation capabilities and how complex is it to enable the caching of the images.

Test application

My colleague Oleg just recently published a post on getting started with retrofit. His project is available on Github, so I just forked it and tweaked it a bit to add the image loading scenario. The app just pulls the contributors of a company and a repository and displays the result in a list. I’ll just add the avatar loading part to the app.

It’s important to keep business logic and implementation very separate. So I’ll hide the image loading implementation behind an interface, that takes 2 arguments, a String for my url and an ImageView where the bitmap should be loaded to.

Getting started with Picasso

The Picasso github site gives a very easy and straightforward guide to get the library up and running.

Step 1. add the Gradle dependency to your android module build.gradle:

compile 'com.squareup.picasso:picasso:2.5.2'

Step 2. implement the loadImage(String url, ImageView imageView) method with Picasso:

public void loadImage(String url, ImageView imageView) {

Step 3. Apply changes and observe your images being loaded! Thanks to JRebel for Android, this step took literally an instant for me (sorry, shameless plug).

Step 4. I’ll also add a placeholder and an error image to the constructor.


And we have nice looking images in the application. Pretty simple and sweet!

Android Picasso Images Loading

Keep in mind that just setting drawable in ImageView’s xml with android:src="@android:drawable/sym_contact_card" will not display a placeholder in the list view!

Manipulating the bitmap

The most reasonable way to make crazy visual changes to an image is on the bitmap level. We could do a custom ImageView implementation as well, but this means that each of our drawings will be more expensive performance wise. Also the bitmap should be cached after the transformation is in memory. Picasso is easy and provides the bitmap we want to manipulate in the transform method.

I’m not going to draw the avatars inside a circle. I’ll try something a bit more complicated – I’ll try to draw a 180 degree rotated, mirrored bitmap in the size of ⅓ height under the original image and blur it.

Why would I want to do this? Because I can! And because in my mind, the end result would look really pretty!

Transformations – Picasso!

Well that’s the API, I can use the transformation() method to provide my implementation of the Transformation. A quick Google also pointed me to an additional library that can blur an image for me, so I’ll use that. I’ll still do the mirroring and rotating myself though.

First I’ll add the Picasso Transformations library to my test application. Once again in the Android application module build.gradle I’ll add:

compile 'jp.wasabeef:picasso-transformations:1.3.1'

Moving on to the PicassoImageLoader.loadImage(). I’ll also provide a new Transformation. In code, Transformation is an interface that defines two methods – transform() and key(). As part of the transform process we’ll get the downloaded bitmap object which we’ll have to modify and return, complete with our changes. The key() is used for caching purposes.

    public void loadImage(String url, ImageView imageView) {
        Picasso.with(imageView.getContext()).load(url).transform(new Transformation() {
            public Bitmap transform(Bitmap source) {
                return null;

            public String key() {
                return null;

In the transform method I can work my magic and manipulate the bitmap that I downloaded, as follows:

public Bitmap transform(Bitmap source) {
 //Create a new and slightly higher bitmap where 2 images will be drawn
 Bitmap combinedBitmap = Bitmap.createBitmap(source.getWidth(), source.getHeight() / 3 + source.getHeight(), source.getConfig());
 //Canvas to draw the original bitmap to the top part
 Canvas comboImage = new Canvas(combinedBitmap);
 comboImage.drawBitmap(source, 0f, 0f, null);
 //Matrix to rotate, mirror and reposition the bitmap underneath the original bitmap
 Matrix matrix = new Matrix();
 matrix.preScale(-1, 1);
 matrix.postTranslate(0, source.getHeight() * 2);
 //Do a blur transformation using the library
 BlurTransformation blurTransformation = new BlurTransformation(imageView.getContext(), 10, 1);
 //Get the bitmap object from the transformation
 Bitmap bottom = blurTransformation.transform(source);
  //Set the matrix to the canvas to apply the previous modifications
  //Draw the second bitmap with transformation, rotation, mirroring and translation
  comboImage.drawBitmap(bottom, 0f, 0f, null);

In short the code above:

  • Creates a combined bitmap object that will increase the height by ⅓ of the original image.
  • Draws the initial bitmap onto the combined canvas.
  • Create a matrix that mirrors, rotates and translates the position of the downloaded bitmap object.
  • Blurs the source bitmap
  • Draws the blurred, rotated, mirrored bitmap to the combined canvas.

Here’s how it looks on my emulator now:

android picasso image loading result

Is it optimal? Unlikely, but it works for my proof of concept little app. The listview scrolling performance isn’t suffering either, images are drawn with a slight delay as they have to be transformed again after being deleted from the memory cache.

In addition I had to implement the key() method:

public String key() {
  return PicassoImageLoader.class.getName() + ".Transformation";


For offline or disk caching you need to have to use the okhttp client in your project. There is no need to add config or do anything specific with your API calls. Okhttp client will be automatically used if present. As I already use Retrofit I have no need to include the okhttp dependency manually. By default when Picasso is initialized its memory cache will be 15% of the available application RAM and 2% storage space up to 50MB, but no less than 5MB. I’m sure, this is a sensible default, and without refined use-cases and solid evidence that it’s not enough you probably should not change it.


Lists and images are two things that almost every Android developer will need to understand how to use in their development career. In this post we looked at Picasso, which is allegedly the simplest and the most user-friendly image loading library for Android. We got it to display images in a listview and additionally crafted a peculiar transformation which enhanced our images. Isn’t it amazing? Check out the source of the sample app to see how it all gets together and how easy it is to use Picasso.

In the next post in the series we will take a look at Glide, the image loading & manipulation library by google. See you then! Oh and let me know your thoughts in the comments section below. Have you used Picasso before? What were your experiences?

Read next: