Library to handle asynchronous image loading on Android.

Overview

WebImageLoader

WebImageLoader is a library designed to take to hassle out of handling images on the web. It has the following features:

  • Images are downloaded on a background thread pool and saved to disk and memory.
  • Disk and memory cache size is configurable and can even be reconfigured on the fly.
  • Separate thread do load images back from disk after being cached, reducing I/O bottlenecks on most phones.
  • Reusing requests when the same image is requested multiple times.
  • Respects cache-control and expires headers and will refetch images when they expire (using conditional get).
  • Support image transformations which are also cached to disk and memory.
  • Support to do synchronous fetches while still taking advantage of the cache.
  • Support for download progress callbacks.
  • Easy setup without singletons.
  • Compatible with API level 7 and up.
  • Only depends on DiskLruCache.

Usage

Use the builder to build an ImageLoader that suits your needs.

// Get memory class of this device, exceeding this amount will throw an
// OutOfMemory exception.
ActivityManager am = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
int memClass = am.getMemoryClass();

// Use part of the available memory for memory cache.
final int memoryCacheSize = 1024 * 1024 * memClass / 8;

File cacheDir = new File(getExternalCacheDir(), "images");
ImageLoader imageLoader = new ImageLoader.Builder(context)
        .enableDiskCache(cacheDir, 10 * 1024 * 1024)
        .enableMemoryCache(memoryCacheSize).build();

Or use the provided Applications class for convenience and reasonable defaults (which you can override!)

<application android:name="com.webimageloader.ext.ImageLoaderApplication">
    <!-- Your app -->
</application>

Retrive your loader like this.

ImageLoader imageLoader = ImageLoaderApplication.getLoader(context);

Loading images

Loading images is simple if you want it to be.

// This will show a nice fade in when the image has loaded
new ImageHelper(context, imageLoader)
        .setFadeIn(true)
        .load(imageView, "http://example.com/image.png");

You can also use specify a loading and failure image

new ImageHelper(context, imageLoader)
        .setLoadingResource(R.drawable.loading)
        .setErrorResource(R.drawable.error)
        .load(imageView, "http://example.com/image.png");

Loading images can also be done more explicit if needed.

Bitmap b = loader.load(imageView, "http://example.com/image.png", new Listener<ImageView>() {
    @Override
    public void onSuccess(ImageView v, Bitmap b) {
        // Everything went well
        v.setImageBitmap(b);
    }

    @Override
    public void onError(ImageView v, Throwable t) {
        // Something went wrong
        Log.d("MyApp", "Failed to load image", t);
    }
});

// Did we get an image immediately?
if (b != null) {
    imageView.setImageBitmap(b);
}

Transformations

You can transform (and cache!) the images you get.

final int width = 100;
final int height = 100;
        
Transformation t = new SimpleTransformation() {
    @Override
    public String getIdentifier() {
        // Pass a unique identifier for caching
        return "scale-" + width + "x" + height;
    }
    
    @Override
    public Bitmap transform(Bitmap b) {
        return Bitmap.createScaledBitmap(b, width, height, true);
    }
};

new ImageHelper(this, imageLoader)
        .load(imageView, "http://example.com/image.png", t);

Progress

Progress is easy if you have a ProgressBar, it will only be shown when when needed.

// Automatically update the progress bar
new ImageHelper(context, imageLoader)
        .load(imageView, progressBar, "http://example.com/image.png");

Or handle progress yourself.

Bitmap b = loader.load(imageView, "http://example.com/image.png", new Listener<ImageView>() {
    @Override
    public void onSuccess(ImageView v, Bitmap b) {
        // Same as above
    }

    @Override
    public void onError(ImageView v, Throwable t) {
        // Same as above
    }
}, new ProgressListener() {
    @Override
    public void onProgress(float value) {
        // value is in the range 0f-1f
    }
});

Obtaining

You can include the library by downloading the .jar and also adding DiskLruCache to your project.

If you are a Maven user, simply add the following to your pom.xml:

<dependency>
    <groupId>com.webimageloader</groupId>
    <artifactId>webimageloader</artifactId>
    <version>1.2.0</version>
</dependency>

Developed By

License

WebImageLoader is licensed under Apache 2.0. If you find this library useful feel free to send me a tweet (or not).

Copyright 2012 Alexander Blom

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

   http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
Comments
  • Support redirects

    Support redirects

    Images that are being redirected fail to load.

    Example:

    Loading the URL http://api.twitter.com/1/users/profile_image?screen_name=bdesmet_&size=bigger fails with the following error message:

    09-18 20:37:20.653: D/skia(16308): --- SkImageDecoder::Factory returned null 09-18 20:37:20.669: D/ImageHelper(16308): Error loading bitmap 09-18 20:37:20.669: D/ImageHelper(16308): java.io.IOException: Failed to create bitmap, decodeStream() returned null 09-18 20:37:20.669: D/ImageHelper(16308): at com.webimageloader.util.BitmapUtils.decodeStream(BitmapUtils.java:42) 09-18 20:37:20.669: D/ImageHelper(16308): at com.webimageloader.loader.PendingRequests$RequestListener.onStreamLoaded(PendingRequests.java:144) 09-18 20:37:20.669: D/ImageHelper(16308): at com.webimageloader.loader.NetworkLoader.loadInBackground(NetworkLoader.java:94) 09-18 20:37:20.669: D/ImageHelper(16308): at com.webimageloader.loader.BackgroundLoader$1.run(BackgroundLoader.java:22) 09-18 20:37:20.669: D/ImageHelper(16308): at com.webimageloader.concurrent.ListenerFuture.run(ListenerFuture.java:21) 09-18 20:37:20.669: D/ImageHelper(16308): at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:442) 09-18 20:37:20.669: D/ImageHelper(16308): at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:305) 09-18 20:37:20.669: D/ImageHelper(16308): at java.util.concurrent.FutureTask.run(FutureTask.java:137) 09-18 20:37:20.669: D/ImageHelper(16308): at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1076) 09-18 20:37:20.669: D/ImageHelper(16308): at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:569) 09-18 20:37:20.669: D/ImageHelper(16308): at java.lang.Thread.run(Thread.java:856) 09-18 20:37:20.669: D/ImageHelper(16308): at com.webimageloader.util.PriorityThreadFactory$1.run(PriorityThreadFactory.java:26)

    If you load the URL to which the first URL redirects (https://si0.twimg.com/profile_images/1593219329/333834_10150325451617266_569922265_8295088_379754916_o_bigger.jpg) everything works fine.

    opened by litrik 13
  • Use HttpResponseCache (or similar) instead of reimplementing HTTP caching

    Use HttpResponseCache (or similar) instead of reimplementing HTTP caching

    I noticed that you reimplement HTTP caching (respecting etags and other headers) when Android 4.0 and later does this for you - see https://developer.android.com/reference/android/net/http/HttpResponseCache.html To support versions of Android before 4.0, you could use my library: https://github.com/candrews/httpresponsecache

    I only point this out as implementing these parts of the HTTP protocol aren't easy, and I haven't examined your code terribly closely, but I'd be willing to bet it isn't up to feature parity or have as few bugs as the Android implementation. You could probably save yourself a lot of maintenance headache by reusing a library for this.

    opened by candrews 4
  • Image from disk cache is without transparent background

    Image from disk cache is without transparent background

    Hi,

    First I must say it's the best image loading library for android that I've found so far. Thanks for this awesome work!

    I've tried to use it in my project, I'm using transformation to make the image rounded. Everything works amazing, but when the disk cache is enabled and the image being loaded from the cache, it's being displayed with black background instead of transparent background in the area that was clipped (attached picture). image

    Is it a configuration that I'm missing or a bug? BTW, in which format the image being saved in the cache, because if it's the same format as the original image and it doesn't support transparency, it might be the root for the problem.

    Would love to get some help with that! Thanks, Lior

    opened by liorix 3
  • Create load function which retrieves the path to the file instead of a Bitmap

    Create load function which retrieves the path to the file instead of a Bitmap

    How about creating a duplicate of the load function which would retrieve the URI path to the downloaded/cached file (or null) instead of a Bitmap instance ?

    This would be neat to integrate you library into an image gallery (imageviews inside view pager) without putting all the bitmaps in memory.

    opened by arnaudbos 3
  • Custom header attributes for request

    Custom header attributes for request

    To support e.g. https basic auth mechnism or addtional header attributes that are required to gain access to an image resource it should be possible to add custom header parameters to the request.

    opened by atomfrede 3
  • Not possible to request images over HTTPS

    Not possible to request images over HTTPS

    The error occurs when trying to use a custom ConnectionFactory for HTTPS

    I downloaded the code and found the error. On constructor of class NetworkLoader is missing the code below this.connectionFactory = builder.connectionFactory

    opened by condesales 2
  • Disk Cache not cacheing last image

    Disk Cache not cacheing last image

    Just playing about with this under no network conditions and it seems that the last item to be fetched by the loader doesn't get committed to the disk cache.

    Steps to reproduce:

    1. Navigate to activity that uses webimageloader (e.g. listview activity)
    2. Exit to home screen and remove app from recents launcher to evict from memory
    3. Put phone into airplane mode
    4. Navigate back to activity in 1. All images are fetched except one (usually the last image in the list)

    (ddms says ImageLoader: Error loading bitmap)

    opened by damianflannery 2
  • Allow users to specify a custom HttpURLConnection.

    Allow users to specify a custom HttpURLConnection.

    As discussed in issue #11, this allows the use of libraries like OkHttp to work around various native Android HTTP bugs.

    I don't know if these changes were exactly what you were thinking of, but this works well for me (with a patched version of OkHttp which properly handles HTTP 307 redirects).

    I tested it with no ConnectionHandler, a handler which always returns null and a handler which uses OkHttp. Everything worked as expected.

    opened by orrc 2
  • Background fix

    Background fix

    When using a square image as a placeholder and downloading a rounded corner image (with fade animation), it is important to remove the placeholder and do the fade in animation. android:background and android:src for an imageview are different properties.

    opened by josomers 2
  • Packages and Eclipse

    Packages and Eclipse

    Hi... if I try to import the code of the directory "webimagloader" in eclipse as a "excisting Code Android Project" i get errors because your package-declaration "com.webimageloader" does not fit your directory-structure "main.java.com.webimageloader". This is necessary for eclipse. I wonder if i'm doing something wrong or maybe dont know something. Why do you have this structure? Greets, Mate

    opened by matecode 1
  • LruCache and recycle bitmaps

    LruCache and recycle bitmaps

    Maybe you should have a look at this library: https://github.com/chrisbanes/Android-BitmapMemoryCache It uses the LruCache, but also recycles the bitmap if it isn't displayed or cached.

    declined 
    opened by ghost 1
  • Bump gson from 2.2.3 to 2.8.9 in /sample

    Bump gson from 2.2.3 to 2.8.9 in /sample

    Bumps gson from 2.2.3 to 2.8.9.

    Release notes

    Sourced from gson's releases.

    Gson 2.8.9

    • Make OSGi bundle's dependency on sun.misc optional (#1993).
    • Deprecate Gson.excluder() exposing internal Excluder class (#1986).
    • Prevent Java deserialization of internal classes (#1991).
    • Improve number strategy implementation (#1987).
    • Fix LongSerializationPolicy null handling being inconsistent with Gson (#1990).
    • Support arbitrary Number implementation for Object and Number deserialization (#1290).
    • Bump proguard-maven-plugin from 2.4.0 to 2.5.1 (#1980).
    • Don't exclude static local classes (#1969).
    • Fix RuntimeTypeAdapterFactory depending on internal Streams class (#1959).
    • Improve Maven build (#1964).
    • Make dependency on java.sql optional (#1707).

    Gson 2.8.8

    • Fixed issue with recursive types (#1390).
    • Better behaviour with Java 9+ and Unsafe if there is a security manager (#1712).
    • EnumTypeAdapter now works better when ProGuard has obfuscated enum fields (#1495).
    Changelog

    Sourced from gson's changelog.

    Version 2.8.9

    • Make OSGi bundle's dependency on sun.misc optional (#1993).
    • Deprecate Gson.excluder() exposing internal Excluder class (#1986).
    • Prevent Java deserialization of internal classes (#1991).
    • Improve number strategy implementation (#1987).
    • Fix LongSerializationPolicy null handling being inconsistent with Gson (#1990).
    • Support arbitrary Number implementation for Object and Number deserialization (#1290).
    • Bump proguard-maven-plugin from 2.4.0 to 2.5.1 (#1980).
    • Don't exclude static local classes (#1969).
    • Fix RuntimeTypeAdapterFactory depending on internal Streams class (#1959).
    • Improve Maven build (#1964).
    • Make dependency on java.sql optional (#1707).

    Version 2.8.8

    • Fixed issue with recursive types (#1390).
    • Better behaviour with Java 9+ and Unsafe if there is a security manager (#1712).
    • EnumTypeAdapter now works better when ProGuard has obfuscated enum fields (#1495).

    Version 2.8.7

    • Fixed ISO8601UtilsTest failing on systems with UTC+X.
    • Improved javadoc for JsonStreamParser.
    • Updated proguard.cfg (#1693).
    • Fixed IllegalStateException in JsonTreeWriter (#1592).
    • Added JsonArray.isEmpty() (#1640).
    • Added new test cases (#1638).
    • Fixed OSGi metadata generation to work on JavaSE < 9 (#1603).

    Version 2.8.6

    2019-10-04 GitHub Diff

    • Added static methods JsonParser.parseString and JsonParser.parseReader and deprecated instance method JsonParser.parse
    • Java 9 module-info support

    Version 2.8.5

    2018-05-21 GitHub Diff

    • Print Gson version while throwing AssertionError and IllegalArgumentException
    • Moved utils.VersionUtils class to internal.JavaVersion. This is a potential backward incompatible change from 2.8.4
    • Fixed issue google/gson#1310 by supporting Debian Java 9

    Version 2.8.4

    2018-05-01 GitHub Diff

    • Added a new FieldNamingPolicy, LOWER_CASE_WITH_DOTS that mapps JSON name someFieldName to some.field.name
    • Fixed issue google/gson#1305 by removing compile/runtime dependency on sun.misc.Unsafe

    Version 2.8.3

    2018-04-27 GitHub Diff

    • Added a new API, GsonBuilder.newBuilder() that clones the current builder
    • Preserving DateFormatter behavior on JDK 9

    ... (truncated)

    Commits
    • 6a368d8 [maven-release-plugin] prepare release gson-parent-2.8.9
    • ba96d53 Fix missing bounds checks for JsonTreeReader.getPath() (#2001)
    • ca1df7f #1981: Optional OSGi bundle's dependency on sun.misc package (#1993)
    • c54caf3 Deprecate Gson.excluder() exposing internal Excluder class (#1986)
    • e6fae59 Prevent Java deserialization of internal classes (#1991)
    • bda2e3d Improve number strategy implementation (#1987)
    • cd748df Fix LongSerializationPolicy null handling being inconsistent with Gson (#1990)
    • fe30b85 Support arbitrary Number implementation for Object and Number deserialization...
    • 1cc1627 Fix incorrect feature request template label (#1982)
    • 7b9a283 Bump bnd-maven-plugin from 5.3.0 to 6.0.0 (#1985)
    • Additional commits viewable in compare view

    Dependabot compatibility score

    Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


    Dependabot commands and options

    You can trigger Dependabot actions by commenting on this PR:

    • @dependabot rebase will rebase this PR
    • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
    • @dependabot merge will merge this PR after your CI passes on it
    • @dependabot squash and merge will squash and merge this PR after your CI passes on it
    • @dependabot cancel merge will cancel a previously requested merge and block automerging
    • @dependabot reopen will reopen this PR if it is closed
    • @dependabot close will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
    • @dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
    • @dependabot use these labels will set the current labels as the default for future PRs for this repo and language
    • @dependabot use these reviewers will set the current reviewers as the default for future PRs for this repo and language
    • @dependabot use these assignees will set the current assignees as the default for future PRs for this repo and language
    • @dependabot use this milestone will set the current milestone as the default for future PRs for this repo and language

    You can disable automated security fix PRs for this repo from the Security Alerts page.

    dependencies 
    opened by dependabot[bot] 0
  • Some images are always loaded from the network

    Some images are always loaded from the network

    Some images are always re-loaded from the network.

    Examle img url: http://sga-book.ru/files/3383.04.01;Т-Т.01;2/images/image035.jpg

    V/NetworkLoader﹕ Loaded http://sga-book.ru/files/3383.04.01;Т-Т.01;2/images/image035.jpg from network ....

    Build ImageLoader in default param in ImageLoaderApplication.java

    opened by gewisser 0
  • Not able to load certain URLs

    Not able to load certain URLs

    If the URL have an %20, %2F or some other character like those, the image is not loaded. Getting D/ImageHelper﹕ Error loading bitmap

    A fix could be parse the URL to remove this characters.

    opened by condesales 0
  • Flag to ignore cache and force reload

    Flag to ignore cache and force reload

    Hi,

    Like I said on the previous message, thanks for your contribution. Your code is one of the bests for me.

    And, I have only one more issue with this code. I need to set some flag on the API to ignore cache and force the image reload.

    Because, I have a form that the user can change the image (profile picture), and after the new upload I call the the API to open the image, but it returns the obsolete cache picture.

    Can you please help me on that?

    Thanks,

    Ricardo

    opened by ricardopaulob 4
  • Allow to post xml with the request

    Allow to post xml with the request

    Hi,

    I think your api very cool. It solved all my problems to load images. Thank you very much for your contribuition.

    But, I still need two little things to can use this API in my App. First, I need to verify the user permission to see the image. So my webservice is prepared to receive a XML post with the login details, to confirm permissions.

    Something like this: HttpClient httpclient = new DefaultHttpClient(); HttpPost httppost = new HttpPost(requestURL); StringEntity se = new StringEntity(requestXMLMessage, HTTP.ISO_8859_1); se.setContentType(text/xml); httppost.setEntity(se);

    It is possible to add the usability on this custom request to load images?

    Thank you very much,

    Ricardo

    opened by ricardopaulob 0
  • Pause async loader on scroll

    Pause async loader on scroll

    Is there any way to pause the async tasks? Reason I ask, is to pause the background threads while scrolling as there's too much work being done as the images scroll by for a listview with large number of images.

    So, on scroll, I would pause the work and on scroll stop, I would resume the work.

    Thanks, Bhaskar

    opened by bhaskarmurthy 2
Owner
Alexander Blom
Alexander Blom
An image loading and caching library for Android focused on smooth scrolling

Glide | View Glide's documentation | 简体中文文档 | Report an issue with Glide Glide is a fast and efficient open source media management and image loading

Bump Technologies 33.2k Jan 7, 2023
🍂 Jetpack Compose image loading library which can fetch and display network images using Glide, Coil, and Fresco.

?? Jetpack Compose image loading library which can fetch and display network images using Glide, Coil, and Fresco.

Jaewoong Eum 1.4k Jan 2, 2023
Image loading for Android backed by Kotlin Coroutines.

An image loading library for Android backed by Kotlin Coroutines. Coil is: Fast: Coil performs a number of optimizations including memory and disk cac

Coil 8.8k Jan 8, 2023
Bitmap decoder, handle resize & quality & compress stuff following user's configurations.

SoBitmap SoBitmap is not an ImageLoader, it born for process single bitmap. Some conditions, we want a image displayed in some limit, such as the max

Kevin Liu 87 Aug 1, 2019
Bitmap decoder, handle resize & quality & compress stuff following user's configurations.

SoBitmap SoBitmap is not an ImageLoader, it born for process single bitmap. Some conditions, we want a image displayed in some limit, such as the max

Kevin Liu 87 Aug 1, 2019
Powerful and flexible library for loading, caching and displaying images on Android.

Universal Image Loader The great ancestor of modern image-loading libraries :) UIL aims to provide a powerful, flexible and highly customizable instru

Sergey Tarasevich 16.8k Jan 8, 2023
A powerful image downloading and caching library for Android

Picasso A powerful image downloading and caching library for Android For more information please see the website Download Download the latest AAR from

Square 18.4k Jan 6, 2023
An Android transformation library providing a variety of image transformations for Glide.

Glide Transformations An Android transformation library providing a variety of image transformations for Glide. Please feel free to use this. Are you

Daichi Furiya 9.7k Dec 30, 2022
An android image compression library.

Compressor Compressor is a lightweight and powerful android image compression library. Compressor will allow you to compress large photos into smaller

Zetra 6.7k Jan 9, 2023
An Android transformation library providing a variety of image transformations for Picasso

Picasso Transformations An Android transformation library providing a variety of image transformations for Picasso. Please feel free to use this. Are

Daichi Furiya 1.7k Jan 5, 2023
Compose Image library for Kotlin Multiplatform.

Compose ImageLoader Compose Image library for Kotlin Multiplatform. Setup Add the dependency in your common module's commonMain sourceSet kotlin {

Seiko 45 Dec 29, 2022
Image Picker for Android 🤖

Image Picker for Android ??

Esa Firman 1k Dec 31, 2022
Luban(鲁班)—Image compression with efficiency very close to WeChat Moments/可能是最接近微信朋友圈的图片压缩算法

Luban ?? English Documentation Luban(鲁班) —— Android图片压缩工具,仿微信朋友圈压缩策略。 Luban-turbo —— 鲁班项目的turbo版本,查看trubo分支。 写在前面 家境贫寒,工作繁忙。只能不定期更新,还望网友们见谅! 项目描述 目前做A

郑梓斌 13.1k Jan 7, 2023
ZoomableComposeImage - A zoomable image for jetpack compose

ZoomableComposeImage - A zoomable image for jetpack compose

RERERE 10 Dec 11, 2022
ComposeImageBlurhash is a Jetpack Compose component with the necessary implementation to display a blurred image

compose-image-blurhash ComposeImageBlurhash is a Jetpack Compose component with the necessary implementation to display a blurred image while the real

Orlando Novas Rodriguez 24 Nov 18, 2022
Easy to use, lightweight custom image view with rounded corners.

RoundedImageView Easy to use, lightweight custom image view with rounded corners. Explore the docs » View Demo · Report Bug · Request Feature About Th

Melik Mehmet Özyildirim 6 Dec 23, 2021
load-the-image Apply to compose-jb(desktop), Used to load network and local pictures.

load-the-image load-the-image Apply to compose-jb(desktop), Used to load network and local pictures. ?? Under construction It may change incompatibly

lt_taozi 13 Dec 29, 2022
An Android library for managing images and the memory they use.

Fresco Fresco is a powerful system for displaying images in Android applications. Fresco takes care of image loading and display, so you don't have to

Facebook 16.9k Jan 8, 2023
Photo picker library for android. Let's you pick photos directly from files, or navigate to camera or gallery.

ChiliPhotoPicker Made with ❤️ by Chili Labs. Library made without DataBinding, RxJava and image loading libraries, to give you opportunity to use it w

Chili Labs 394 Jan 2, 2023