B4A Library Picasso image downloading and caching library

Picasso is A powerful image downloading and caching library for Android.

The existing b4a ImageDownloader module does much the same as Picasso but Picasso's main advantage that it can perform various image transformations for you.

Picasso consists of three object: Picasso, RequestBuilder and DefaultTarget:

Picasso
Comment:
Picasso is an open source library that manages the loading of images in your application.
http://square.github.io/picasso/
Licensed under the Apache License, version 2.0:
http://www.apache.org/licenses/LICENSE-2.0
Author: Martin Pearman
Version: 1
  • DefaultTarget
    Events:
    • Error (Tag As Object)
    • Success (Bitmap1 As Bitmap, Tag As Object)
    Methods:
    • Initialize (EventName As String, Tag As Object)
    • IsInitialized As Boolean
  • Picasso
    Methods:
    • CancelRequest (ImageView1 As ImageView)
      Cancel any existing requests for the specified target ImageView1.
    • CancelRequest2 (Target1 As Target)
      Cancel any existing requests for the specified Target instance.
    • Initialize
    • IsDebugging As Boolean
      Returns True if debug display, logging, and statistics are enabled.
    • IsInitialized As Boolean
    • LoadFile (FilePath As String) As RequestBuilder
      Start an image request using the specified image file path.
    • LoadResource (ResourceName As String) As RequestBuilder
      Start an image request using the specified drawable resource.
    • LoadUrl (Url As String) As RequestBuilder
      Start an image request using the specified URL.
    • SetDebugging (Debugging As Boolean)
      Set whether debug display, logging, and statistics are enabled.
    Permissions:
    • android.permission.INTERNET
  • RequestBuilder
    Methods:
    • CenterCrop As RequestBuilder
      Crops an image inside of the bounds specified by Resize(TargetWidth, TargetHeight) rather than distorting the aspect ratio.
      CenterCrop can only be used after calling Resize.
    • CenterInside As RequestBuilder
      CenterInside can only be used after calling Resize.
    • ErrorDrawable (ErrorDrawable As Drawable) As RequestBuilder
      Set a Drawable to be used if the requested image could not be loaded.
    • ErrorResource (ResourceName As String) As RequestBuilder
      Set a drawable resource to be used if the requested image could not be loaded.
    • Fetch (Target1 As Target)
      Asynchronously fulfils the request into the specified Target1.
    • Fit As RequestBuilder
      Attempt to resize the image to fit exactly into the target ImageView's bounds.
    • Get As BitmapWrapper
      Synchronously fulfill this request.
    • IntoImageView (ImageView1 As ImageView)
      Asynchronously fulfils the request into the specified ImageView.
    • IntoTarget (Target1 As Target)
      Asynchronously fulfils the request into the specified Target.
      See also the RequestBuilder Fetch method.
    • IsInitialized As Boolean
    • NoFade As RequestBuilder
      Disable brief fade in of images loaded from the disk cache or network.
    • PlaceholderDrawable (PlaceholderDrawable As Drawable) As RequestBuilder
      Set a Drawable to be used while the requested image is being loaded.
    • PlaceholderResource (ResourceName As String) As RequestBuilder
      Set a drawable resource to be used while the requested image is being loaded.
    • Resize (TargetWidth As Int, TargetHeight As Int) As RequestBuilder
      Resize the image to the specified size in pixels.
    • ResizeDimen (TargetWidthResourceName As String, TargetHeightResourceName As String) As RequestBuilder
      Resize the image to the specified resource dimensions size.
    • Rotate (Degrees As Float) As RequestBuilder
      Rotate the image by the specified degrees.
    • Rotate2 (Degrees As Float, PivotX As Float, PivotY As Float) As RequestBuilder
      Rotate the image by the specified degrees around the specified pivot point.
    • Scale (Factor As Float) As RequestBuilder
      Scale the image using the specified factor.
    • Scale2 (FactorX As Float, FactorY As Float) As RequestBuilder
      Scale the image using the specified factors.
    • SkipCache As RequestBuilder
      Indicate that this request should not use the memory cache for attempting to load or save the image.
    • Transform (Transformation1 As Transformation) As RequestBuilder
      Add a custom transformation to be applied to the image.
      ** The Transformation interface is not currently implemented so this method has no use **


As a simple image downloader you can use Picasso to download an image and then set the downloaded image as an ImageView Bitmap:

B4X:
Picasso1.LoadUrl("http://i.imgur.com/DvpvklR.png").IntoImageView(ImageView1)

The DefaultTarget object offers an alternative syntax.
Instead of Picasso setting the downloaded image as an ImageView Bitmap it can raise an event and pass the downloaded Bitmap to a b4a Sub:

B4X:
Dim Target1 As DefaultTarget
Target1.Initialize("Target1", "MyTagValue")
Picasso1.LoadUrl("http://i.imgur.com/DvpvklR.png").Fetch(Target1)

Sub Target1_Error(Tag As Object)
   Log("Target1_Error Tag="&Tag)
End Sub

Sub Target1_Success(Bitmap1 As Bitmap, Tag As Object)
   Log("Target1_Success Tag="&Tag)
   If Tag="MyTagValue" Then
     '   do something with the Bitmap
   End If
End Sub

So using the DefaultTarget allows you to do whatever you want to do with the downloaded image.

Picasso manages downloaded images with an in-memory cache and a disk cache, it'll retrieve an image from the caches if possible before trying to download the image.
When Picasso does download an image from the internet it looks at the various HTTP cache instruction headers that accompany the image.
Picasso then decides how long to cache the downloaded image to memory or disk based on these HTTP headers.

Another useful feature of Picasso is it's ability to display 'image downloading' and 'image download failed' placeholder images.

I've created two example projects.
One shows the use of loading an image into an ImageView with the various transformation and placeholder options.
The other is a simple example showing how to use the DefaultTarget.

Library and example projects are attached.
Please read the readme.txt file in the library download.

Martin.
 

Attachments

  • Picasso_examples.zip
    226.6 KB · Views: 1,682
  • Picasso_all_library_files_v1_00.zip
    52.5 KB · Views: 1,976
Last edited:

Informatix

Expert
Licensed User
Longtime User
I have a problem with your DefaultTarget example. When I click on Go!, nothing (visible) happens. If I run this example a second time, all works fine. I removed it from the device and reinstalled it. Same behavior. Nothing on the first run.
 

warwound

Expert
Licensed User
Longtime User
That's odd.
On my 7" Tab2 i can replicate the problem.
When testing the library i guess i didn't completely uninstall the test program before making any changes.

Anyway if you look at the documentation you'll see there is a RequestBuilder method Fetch (Target1 As Target):
Asynchronously fulfils the request into the specified Target1.

I updated the example, changing just the Button1_Click Sub so that it uses Fetch instead of IntoTarget:

B4X:
Sub Button1_Click
   Button1.RemoveView
  
   Dim Picasso1 As Picasso
   Picasso1.Initialize
   
   Dim Target1 As DefaultTarget
   Target1.Initialize("Target", "ActivityBackground")
   Picasso1.LoadUrl("http://i.imgur.com/DvpvklR.png").Fetch(Target1)
  
   Dim Target2 As DefaultTarget
   Target2.Initialize("Target", "ImageView")
   Picasso1.LoadUrl("http://banckle.com/images/icons/android-48.png").Fetch(Target2)
End Sub

It works!
I uninstalled and installed it 2 or 3 times and it works fine each time.

Can you test with the Fetch method and confirm it works with no problems?

It might be best for me to remove the IntoTarget method if it is troublesome.

The javadoc for RequestBuilder can be found here: http://square.github.io/picasso/javadoc/index.html.
The java library has two overloaded into() methods, one for ImageView and one for Target.

Martin.
 

warwound

Expert
Licensed User
Longtime User
Ok, i have decided to leave the RequestBuilder IntoTarget method as it is for now, rather than remove it.

I have though updated my first post in this thread.

The documentation for IntoTarget now mentions the Fetch method:

IntoTarget (Target1 As Target)
Asynchronously fulfils the request into the specified Target.
See also the RequestBuilder Fetch method.


The example project has been updated to use Fetch and the updated documentation for the library uploaded.

As i have only added a sentence to the library documentation i have left the library version as 1.00

Martin.
 

ferya

Member
Licensed User
Longtime User
I tried to run first example but got this error
Parsing code. 0.16
Compiling code. 0.41
Compiling layouts code. 0.08
Generating R file. 0.82
Compiling generated Java code. 1.24
Convert byte code - optimized dex. Error
A referenced library is missing: picassonative

and tried to run second , got this.


Parsing code. 0.06
Compiling code. 0.21
Compiling layouts code. 0.01
Generating R file. 0.22
Compiling generated Java code. Error
B4A line: 53
Picasso1.LoadUrl(\
javac 1.7.0_15
src\uk\co\martinpearman\b4a\picassoexample\main.java:279: error: package com.squareup.picasso does not exist
_picasso1.LoadUrl("http://i.imgur.com/DvpvklR.png").Fetch((com.squareup.picasso.Target)(_target1.getObject()));
^
1 error
 

warwound

Expert
Licensed User
Longtime User
Did you follow step two here:

1) Copy both Picasso.jar and Picasso.xml to your b4a additional libraries folder.

2) Download the latest version of the native java android Picasso library.
A download link can be found on the Picasso homepage:
http://square.github.io/picasso/
This downloaded library file will have a name such as picasso-1.1.1.jar and you must rename it to PicassoNative.jar and copy it to your b4a additional libraries folder.

The Picasso library is now ready for use!

Martin.
 

kanaida

Active Member
Licensed User
Longtime User
Can you please update it so the 2.0 library doesn't crash on start? Transformations would be cool too in the future.
 

warwound

Expert
Licensed User
Longtime User
Can you please update it so the 2.0 library doesn't crash on start? Transformations would be cool too in the future.

Ah! I didn't know that the native Picasso library had been updated and that this update broke my b4a library.

Can you post the log that relates to the crash when using Picasso version 2.0?
I'll take a look and see what needs to be done to fix it.

Martin.
 
Last edited:

warwound

Expert
Licensed User
Longtime User
I've now downloaded and tried the new version 2.0 of Picasso and can see the errors.
Version 2.0 of Picasso is in no way backwards compatible with version 1 of Picasso.

I don't know if i'll have time to update the b4a library for a few days, in fact if version 2.0 of Picasso has no new features then it might not be worth my while updating the b4a library.
I shall have to see if i can update the b4a library and keep it backwards compatible.

I'm not sure how many b4a developers have used my Picasso library and whether they'd be happy for an update NOT to be backwards compatible and require them to rewrite their code.

Anyway i shall investigate when i have more time.

Martin.
 

kanaida

Active Member
Licensed User
Longtime User
Thanks. The reason I was trying to update was because loading is pretty shoddy at best when you're loading stuff pretty quickly.
I have about 20 image views that i use as pages with products, If i change page then there's some unfinished requests from the last request on the same view(s) so sometimes I'll get a blank image, or some strangely shaped image for no reason. Cancelling the request on a view then calling a new image to be loaded doesn't make a difference. Possibly not working at all. Unfortunately it's the best solution I have for loading images etc... in a sane manner.
 

warwound

Expert
Licensed User
Longtime User
It's worth taking a few minutes to have a read through the reported issues on the Picasso support group.

A bug in version 2.0 has already been identified and fixed, and version 2.0.1 is now the latest version.
This bug was where an image downloading placeholder was used and the placeholder remained visible after the image had been downloaded.
The fix though is only a partial fix and the placeholder is still likely to be visible while the downloaded image fades in.

I think i shall postpone updating the b4a library for a week or so until the latest version of Picasso has been proved stable and bug free.

@kanaida

Can you post a code example that shows how you are loading your images and how you try to cancel them?
Are you using the IntoImageView, IntoTarget or Fetch method to load the images?

Martin.
 
Last edited:

warwound

Expert
Licensed User
Longtime User
I have now updated the library attachment in post #1, version 1.1.1 of the native Picasso library is now included in the attachment (it's named NativePicasso.jar).
So for the time being anyone wanting to try Picasso can do so and i'll look at the update when the latest Picasso seems more stable.

Martin.
 

Shahid Saeed

Active Member
Licensed User
Longtime User
The Picasso Library had been updated to V. 2.3.2. Do you have any plans to update the b4A library too?
 

warwound

Expert
Licensed User
Longtime User

Shahid Saeed

Active Member
Licensed User
Longtime User

a2stepper

Member
Licensed User
Longtime User
i have downloaded the Picasso library and sample files and really like the simple way to download an image file
and display it.
HOWEVER it is not reliable, some times it works then not work. i did check the script for the changes to the code
and this is how i am using it.
Is there a later version of the library i could download and try.
Again nice work and thanks.

paul
 
Top