Skip to content

Changelog

[2.2.1] - September 8, 2022

  • Fix: RoundedCornersTransformation now properly scales the input bitmap.
  • Remove dependency on the kotlin-parcelize plugin.
  • Update compile SDK to 33.
  • Downgrade androidx.appcompat:appcompat-resources to 1.4.2.
    • This is to work around #1423.

[2.2.0] - August 16, 2022

  • New: Add ImageRequest.videoFramePercent to coil-video to support specifying the video frame as a percent of the video's duration.
  • New: Add ExifOrientationPolicy to configure how BitmapFactoryDecoder treats EXIF orientation data.
  • Fix: Don't throw an exception in RoundedCornersTransformation if passed a size with an undefined dimension.
  • Fix: Read a GIF's frame delay as two unsigned bytes instead of one signed byte.
  • Update Kotlin to 1.7.10.
  • Update Coroutines to 1.6.4.
  • Update Compose to 1.2.1.
  • Update OkHttp to 4.10.0.
  • Update Okio to 3.2.0.
  • Update accompanist-drawablepainter to 0.25.1.
  • Update androidx.annotation to 1.4.0.
  • Update androidx.appcompat:appcompat-resources to 1.5.0.
  • Update androidx.core to 1.8.0.

[2.1.0] - May 17, 2022

  • New: Support loading ByteArrays. (#1202)
  • New: Support setting custom CSS rules for SVGs using ImageRequest.Builder.css. (#1210)
  • Fix: Convert GenericViewTarget's private methods to protected. (#1273)
  • Update compile SDK to 32. (#1268)

[2.0.0] - May 10, 2022

Coil 2.0.0 is a major iteration of the library and includes breaking changes. Check out the upgrade guide for how to upgrade.

  • New: Introduce AsyncImage in coil-compose. Check out the documentation for more info.
// Display an image from the network.
AsyncImage(
    model = "https://example.com/image.jpg",
    contentDescription = null
)

// Display an image from the network with a placeholder, circle crop, and crossfade animation.
AsyncImage(
    model = ImageRequest.Builder(LocalContext.current)
        .data("https://example.com/image.jpg")
        .crossfade(true)
        .build(),
    placeholder = painterResource(R.drawable.placeholder),
    contentDescription = stringResource(R.string.description),
    contentScale = ContentScale.Crop,
    modifier = Modifier.clip(CircleShape)
)
  • New: Introduce a public DiskCache API.
    • Use ImageLoader.Builder.diskCache and DiskCache.Builder to configure the disk cache.
    • You should not use OkHttp's Cache with Coil 2.0. See here for more info.
    • Cache-Control and other cache headers are still supported - except Vary headers, as the cache only checks that the URLs match. Additionally, only responses with a response code in the range [200..300) are cached.
    • Existing disk caches will be cleared when upgrading to 2.0.
  • The minimum supported API is now 21.
  • ImageRequest's default Scale is now Scale.FIT.
    • This was changed to make ImageRequest.scale consistent with other classes that have a default Scale.
    • Requests with an ImageViewTarget still have their Scale auto-detected.
  • Rework the image pipeline classes:
    • Mapper, Fetcher, and Decoder have been refactored to be more flexible.
    • Fetcher.key has been replaced with a new Keyer interface. Keyer creates the cache key from the input data.
    • Add ImageSource, which allows Decoders to read Files directly using Okio's file system API.
  • Rework the Jetpack Compose integration:
    • rememberImagePainter and ImagePainter have been renamed to rememberAsyncImagePainter and AsyncImagePainter respectively.
    • Deprecate LocalImageLoader. Check out the deprecation message for more info.
  • Disable generating runtime not-null assertions.
    • If you use Java, passing null as a not-null annotated argument to a function will no longer throw a NullPointerException immediately. Kotlin's compile-time null safety guards against this happening.
    • This change allows the library's size to be smaller.
  • Size is now composed of two Dimension values for its width and height. Dimension can either be a positive pixel value or Dimension.Undefined. See here for more info.
  • BitmapPool and PoolableViewTarget have been removed from the library.
  • VideoFrameFileFetcher and VideoFrameUriFetcher have been removed from the library. Use VideoFrameDecoder instead, which supports all data sources.
  • BlurTransformation and GrayscaleTransformation are removed from the library. If you use them, you can copy their code into your project.
  • Change Transition.transition to be a non-suspending function as it's no longer needed to suspend the transition until it completes.
  • Add support for bitmapFactoryMaxParallelism, which restricts the maximum number of in-progress BitmapFactory operations. This value is 4 by default, which improves UI performance.
  • Add support for interceptorDispatcher, fetcherDispatcher, decoderDispatcher, and transformationDispatcher.
  • Add GenericViewTarget, which handles common ViewTarget logic.
  • Add ByteBuffer to the default supported data types.
  • Disposable has been refactored and exposes the underlying ImageRequest's job.
  • Rework the MemoryCache API.
  • ImageRequest.error is now set on the Target if ImageRequest.fallback is null.
  • Transformation.key is replaced with Transformation.cacheKey.
  • Update Kotlin to 1.6.10.
  • Update Compose to 1.1.1.
  • Update OkHttp to 4.9.3.
  • Update Okio to 3.0.0.

Changes from 2.0.0-rc03: - Convert Dimension.Original to be Dimension.Undefined. - This changes the semantics of the non-pixel dimension slightly to fix some edge cases (example) in the size system. - Load images with Size.ORIGINAL if ContentScale is None. - Fix applying ImageView.load builder argument first instead of last. - Fix not combining HTTP headers if response is not modified.

[2.0.0-rc03] - April 11, 2022

  • Remove the ScaleResolver interface.
  • Convert Size constructors to functions.
  • Change Dimension.Pixels's toString to only be its pixel value.
  • Guard against a rare crash in SystemCallbacks.onTrimMemory.
  • Update Coroutines to 1.6.1.

[2.0.0-rc02] - March 20, 2022

  • Revert ImageRequest's default size to be the size of the current display instead of Size.ORIGINAL.
  • Fix DiskCache.Builder being marked as experimental. Only DiskCache's methods are experimental.
  • Fix case where loading an image into an ImageView with one dimension as WRAP_CONTENT would load the image at its original size instead of fitting it into the bounded dimension.
  • Remove component functions from MemoryCache.Key, MemoryCache.Value, and Parameters.Entry.

[2.0.0-rc01] - March 2, 2022

Significant changes since 1.4.0:

  • The minimum supported API is now 21.
  • Rework the Jetpack Compose integration.
    • rememberImagePainter has been renamed to rememberAsyncImagePainter.
    • Add support for AsyncImage and SubcomposeAsyncImage. Check out the documentation for more info.
    • Deprecate LocalImageLoader. Check out the deprecation message for more info.
  • Coil 2.0 has its own disk cache implementation and no longer relies on OkHttp for disk caching.
    • Use ImageLoader.Builder.diskCache and DiskCache.Builder to configure the disk cache.
    • You should not use OkHttp's Cache with Coil 2.0 as the cache can be corrupted if a thread is interrupted while writing to it.
    • Cache-Control and other cache headers are still supported - except Vary headers, as the cache only checks that the URLs match. Additionally, only responses with a response code in the range [200..300) are cached.
    • Existing disk caches will be cleared when upgrading to 2.0.
  • ImageRequest's default Scale is now Scale.FIT.
    • This was changed to make ImageRequest.scale consistent with other classes that have a default Scale.
    • Requests with an ImageViewTarget still have their Scale auto-detected.
  • ImageRequest's default size is now Size.ORIGINAL.
  • Rework the image pipeline classes:
    • Mapper, Fetcher, and Decoder have been refactored to be more flexible.
    • Fetcher.key has been replaced with a new Keyer interface. Keyer creates the cache key from the input data.
    • Add ImageSource, which allows Decoders to read Files directly using Okio's file system API.
  • Disable generating runtime not-null assertions.
    • If you use Java, passing null as a not-null annotated parameter to a function will no longer throw a NullPointerException immediately. Kotlin's compile-time null safety guards against this happening.
    • This change allows the library's size to be smaller.
  • Size is now composed of two Dimension values for its width and height. Dimension can either be a positive pixel value or Dimension.Original.
  • BitmapPool and PoolableViewTarget have been removed from the library.
  • VideoFrameFileFetcher and VideoFrameUriFetcher are removed from the library. Use VideoFrameDecoder instead, which supports all data sources.
  • BlurTransformation and GrayscaleTransformation are removed from the library. If you use them, you can copy their code into your project.
  • Change Transition.transition to be a non-suspending function as it's no longer needed to suspend the transition until it completes.
  • Add support for bitmapFactoryMaxParallelism, which restricts the maximum number of in-progress BitmapFactory operations. This value is 4 by default, which improves UI performance.
  • Add support for interceptorDispatcher, fetcherDispatcher, decoderDispatcher, and transformationDispatcher.
  • Add GenericViewTarget, which handles common ViewTarget logic.
  • Add ByteBuffer to the default supported data types.
  • Disposable has been refactored and exposes the underlying ImageRequest's job.
  • Rework the MemoryCache API.
  • ImageRequest.error is now set on the Target if ImageRequest.fallback is null.
  • Transformation.key is replaced with Transformation.cacheKey.
  • Update Kotlin to 1.6.10.
  • Update Compose to 1.1.1.
  • Update OkHttp to 4.9.3.
  • Update Okio to 3.0.0.

Changes since 2.0.0-alpha09:

  • Remove the -Xjvm-default=all compiler flag.
  • Fix failing to load image if multiple requests with must-revalidate/e-tag are executed concurrently.
  • Fix DecodeUtils.isSvg returning false if there is a new line character after the <svg tag.
  • Make LocalImageLoader.provides deprecation message clearer.
  • Update Compose to 1.1.1.
  • Update accompanist-drawablepainter to 0.23.1.

[2.0.0-alpha09] - February 16, 2022

  • Fix AsyncImage creating invalid constraints. (#1134)
  • Add ContentScale argument to AsyncImagePainter. (#1144)
    • This should be set to the same value that's set on Image to ensure that the image is loaded at the correct size.
  • Add ScaleResolver to support lazily resolving the Scale for an ImageRequest. (#1134)
    • ImageRequest.scale should be replaced by ImageRequest.scaleResolver.scale().
  • Update Compose to 1.1.0.
  • Update accompanist-drawablepainter to 0.23.0.
  • Update androidx.lifecycle to 2.4.1.

[2.0.0-alpha08] - February 7, 2022

  • Update DiskCache and ImageSource to use to Okio's FileSystem API. (#1115)

[2.0.0-alpha07] - January 30, 2022

  • Significantly improve AsyncImage performance and split AsyncImage into AsyncImage and SubcomposeAsyncImage. (#1048)
    • SubcomposeAsyncImage provides loading/success/error/content slot APIs and uses subcomposition which has worse performance.
    • AsyncImage provides placeholder/error/fallback arguments to overwrite the Painter that's drawn when loading or if the request is unsuccessful. AsyncImage does not use subcomposition and has much better performance than SubcomposeAsyncImage.
    • Remove AsyncImagePainter.State argument from SubcomposeAsyncImage.content. Use painter.state if needed.
    • Add onLoading/onSuccess/onError callbacks to both AsyncImage and SubcomposeAsyncImage.
  • Deprecate LocalImageLoader. (#1101)
  • Add support for ImageRequest.tags. (#1066)
  • Move isGif, isWebP, isAnimatedWebP, isHeif, and isAnimatedHeif in DecodeUtils into coil-gif. Add isSvg to coil-svg. (#1117)
  • Convert FetchResult and DecodeResult to be non-data classes. (#1114)
  • Remove unused DiskCache.Builder context argument. (#1099)
  • Fix scaling for bitmap resources with original size. (#1072)
  • Fix failing to close ImageDecoder in ImageDecoderDecoder. (#1109)
  • Fix incorrect scaling when converting a drawable to a bitmap. (#1084)
  • Update Compose to 1.1.0-rc03.
  • Update accompanist-drawablepainter to 0.22.1-rc.
  • Update androidx.appcompat:appcompat-resources to 1.4.1.

[2.0.0-alpha06] - December 24, 2021

  • Add ImageSource.Metadata to support decoding from assets, resources, and content URIs without buffering or temporary files. (#1060)
  • Delay executing the image request until AsyncImage has positive constraints. (#1028)
  • Fix using DefaultContent for AsyncImage if loading, success, and error are all set. (#1026)
  • Use androidx LruCache instead of the platform LruCache. (#1047)
  • Update Kotlin to 1.6.10.
  • Update Coroutines to 1.6.0.
  • Update Compose to 1.1.0-rc01.
  • Update accompanist-drawablepainter to 0.22.0-rc.
  • Update androidx.collection to 1.2.0.

[2.0.0-alpha05] - November 28, 2021

  • Important: Refactor Size to support using the image's original size for either dimension.
    • Size is now composed of two Dimension values for its width and height. Dimension can either be a positive pixel value or Dimension.Original.
    • This change was made to better support unbounded width/height values (e.g. wrap_content, Constraints.Infinity) when one dimension is a fixed pixel value.
  • Fix: Support inspection mode (preview) for AsyncImage.
  • Fix: SuccessResult.memoryCacheKey should always be null if imageLoader.memoryCache is null.
  • Convert ImageLoader, SizeResolver, and ViewSizeResolver constructor-like invoke functions to top level functions.
  • Make CrossfadeDrawable start and end drawables public API.
  • Mutate ImageLoader placeholder/error/fallback drawables.
  • Add default arguments to SuccessResult's constructor.
  • Depend on androidx.collection instead of androidx.collection-ktx.
  • Update OkHttp to 4.9.3.

[2.0.0-alpha04] - November 22, 2021

  • New: Add AsyncImage to coil-compose.
    • AsyncImage is a composable that executes an ImageRequest asynchronously and renders the result.
    • AsyncImage is intended to replace rememberImagePainter for most use cases.
    • Its API is not final and may change before the final 2.0 release.
    • It has a similar API to Image and supports the same arguments: Alignment, ContentScale, alpha, ColorFilter, and FilterQuality.
    • It supports overwriting what's drawn for each AsyncImagePainter state using the content, loading, success, and error arguments.
    • It fixes a number of design issues that rememberImagePainter has with resolving image size and scale.
    • Example usages:
// Only draw the image.
AsyncImage(
    model = "https://example.com/image.jpg",
    contentDescription = null // Avoid `null` and set this to a localized string if possible.
)

// Draw the image with a circle crop, crossfade, and overwrite the `loading` state.
AsyncImage(
    model = ImageRequest.Builder(LocalContext.current)
        .data("https://example.com/image.jpg")
        .crossfade(true)
        .build(),
    contentDescription = null,
    modifier = Modifier
        .clip(CircleShape),
    loading = {
        CircularProgressIndicator()
    },
    contentScale = ContentScale.Crop
)

// Draw the image with a circle crop, crossfade, and overwrite all states.
AsyncImage(
    model = ImageRequest.Builder(LocalContext.current)
        .data("https://example.com/image.jpg")
        .crossfade(true)
        .build(),
    contentDescription = null,
    modifier = Modifier
        .clip(CircleShape),
    contentScale = ContentScale.Crop
) { state ->
    if (state is AsyncImagePainter.State.Loading) {
        CircularProgressIndicator()
    } else {
        AsyncImageContent() // Draws the image.
    }
}
  • Important: Rename ImagePainter to AsyncImagePainter and rememberImagePainter to rememberAsyncImagePainter.
    • ExecuteCallback is no longer supported. To have the AsyncImagePainter skip waiting for onDraw to be called, set ImageRequest.size(OriginalSize) (or any size) instead.
    • Add an optional FilterQuality argument to rememberAsyncImagePainter.
  • Use coroutines for cleanup operations in DiskCache and add DiskCache.Builder.cleanupDispatcher.
  • Fix Compose preview for placeholder set using ImageLoader.Builder.placeholder.
  • Mark LocalImageLoader.current with @ReadOnlyComposable to generate more efficient code.
  • Update Compose to 1.1.0-beta03 and depend on compose.foundation instead of compose.ui.
  • Update androidx.appcompat-resources to 1.4.0.

[2.0.0-alpha03] - November 12, 2021

  • Add ability to load music thumbnails on Android 29+. (#967)
  • Fix: Use context.resources to load resources for current package. (#968)
  • Fix: clear -> dispose replacement expression. (#970)
  • Update Compose to 1.0.5.
  • Update accompanist-drawablepainter to 0.20.2.
  • Update Okio to 3.0.0.
  • Update androidx.annotation to 1.3.0.
  • Update androidx.core to 1.7.0.
  • Update androidx.lifecycle to 2.4.0.
    • Remove dependency on lifecycle-common-java8 as it's been merged into lifecycle-common.

[2.0.0-alpha02] - October 24, 2021

  • Add a new coil-bom artifact which includes a bill of materials.
    • Importing coil-bom allows you to depend on other Coil artifacts without specifying a version.
  • Fix failing to load an image when using ExecuteCallback.Immediate.
  • Update Okio to 3.0.0-alpha.11.
    • This also resolves a compatibility issue with Okio 3.0.0-alpha.11.
  • Update Kotlin to 1.5.31.
  • Update Compose to 1.0.4.

[2.0.0-alpha01] - October 11, 2021

Coil 2.0.0 is the next major iteration of the library and has new features, performance improvements, API improvements, and various bug fixes. This release may be binary/source incompatible with future alpha releases until the stable release of 2.0.0.

  • Important: The minimum supported API is now 21.
  • Important: Enable -Xjvm-default=all.
    • This generates Java 8 default methods instead of using Kotlin's default interface method support. Check out this blog post for more information.
    • You'll need to add -Xjvm-default=all or -Xjvm-default=all-compatibility to your build file as well. See here for how to do this.
  • Important: Coil now has its own disk cache implementation and no longer relies on OkHttp for disk caching.
    • This change was made to:
      • Better support thread interruption while decoding images. This improves performance when image requests are started and stopped in quick succession.
      • Support exposing ImageSources backed by Files. This avoids unnecessary copying when an Android API requires a File to decode (e.g. MediaMetadataRetriever).
      • Support reading from/writing to the disk cache files directly.
    • Use ImageLoader.Builder.diskCache and DiskCache.Builder to configure the disk cache.
    • You should not use OkHttp's Cache with Coil 2.0 as it can be corrupted if it's interrupted while writing to it.
    • Cache-Control and other cache headers are still supported - except Vary headers, as the cache only checks that the URLs match. Additionally, only responses with a response code in the range [200..300) are cached.
    • Support for cache headers can be enabled or disabled using ImageLoader.Builder.respectCacheHeaders.
    • Your existing disk cache will be cleared and rebuilt when upgrading to 2.0.
  • Important: ImageRequest's default Scale is now Scale.FIT
    • This was changed to make ImageRequest.scale consistent with other classes that have a default Scale.
    • Requests with an ImageViewTarget still have their scale autodetected.
  • Significant changes to the image pipeline classes:
    • Mapper, Fetcher, and Decoder have been refactored to be more flexible.
    • Fetcher.key has been replaced with a new Keyer interface. Keyer creates the cache key from the input data.
    • Adds ImageSource, which allows Decoders to decode Files directly.
  • BitmapPool and PoolableViewTarget have been removed from the library. Bitmap pooling was removed because:
    • It's most effective on <= API 23 and has become less effective with newer Android releases.
    • Removing bitmap pooling allows Coil to use immutable bitmaps, which have performance benefits.
    • There's runtime overhead to manage the bitmap pool.
    • Bitmap pooling creates design restrictions on Coil's API as it requires tracking if a bitmap is eligible for pooling. Removing bitmap pooling allows Coil to expose the result Drawable in more places (e.g. Listener, Disposable). Additionally, this means Coil doesn't have to clear ImageViews, which has can cause issues.
    • Bitmap pooling is error-prone. Allocating a new bitmap is much safer than attempting to re-use a bitmap that could still be in use.
  • MemoryCache has been refactored to be more flexible.
  • Disable generating runtime not-null assertions.
    • If you use Java, passing null as a not-null annotated parameter to a function will no longer throw a NullPointerException immediately. If you use Kotlin, there is essentially no change.
    • This change allows the library's size to be smaller.
  • VideoFrameFileFetcher and VideoFrameUriFetcher are removed from the library. Use VideoFrameDecoder instead, which supports all data sources.
  • Adds support for bitmapFactoryMaxParallelism, which restricts the maximum number of in-progress BitmapFactory operations. This value is 4 by default, which improves UI performance.
  • Adds support for interceptorDispatcher, fetcherDispatcher, decoderDispatcher, and transformationDispatcher.
  • Disposable has been refactored and exposes the underlying ImageRequest's job.
  • Change Transition.transition to be a non-suspending function as it's no longer needed to suspend the transition until it completes.
  • Add GenericViewTarget, which handles common ViewTarget logic.
  • BlurTransformation and GrayscaleTransformation are removed from the library.
    • If you use them, you can copy their code into your project.
  • ImageRequest.error is now set on the Target if ImageRequest.fallback is null.
  • Transformation.key is replaced with Transformation.cacheKey.
  • ImageRequest.Listener returns SuccessResult/ErrorResult in onSuccess and onError respectively.
  • Add ByteBuffers to the default supported data types.
  • Remove toString implementations from several classes.
  • Update OkHttp to 4.9.2.
  • Update Okio to 3.0.0-alpha.10.

[1.4.0] - October 6, 2021

  • New: Add ImageResult to ImagePainter.State.Success and ImagePainter.State.Error. (#887)
    • This is a binary incompatible change to the signatures of ImagePainter.State.Success and ImagePainter.State.Error, however these APIs are marked as experimental.
  • Only execute CrossfadeTransition if View.isShown is true. Previously it would only check View.isVisible. (#898)
  • Fix potential memory cache miss if scaling multiplier is slightly less than 1 due to a rounding issue. (#899)
  • Make non-inlined ComponentRegistry methods public. (#925)
  • Depend on accompanist-drawablepainter and remove Coil's custom DrawablePainter implementation. (#845)
  • Remove use of a Java 8 method to guard against desugaring issue. (#924)
  • Promote ImagePainter.ExecuteCallback to stable API. (#927)
  • Update compileSdk to 31.
  • Update Kotlin to 1.5.30.
  • Update Coroutines to 1.5.2.
  • Update Compose to 1.0.3.

[1.3.2] - August 4, 2021

  • coil-compose now depends on compose.ui instead of compose.foundation.
    • compose.ui is a smaller dependency as it's a subset of compose.foundation.
  • Update Jetpack Compose to 1.0.1.
  • Update Kotlin to 1.5.21.
  • Update Coroutines to 1.5.1.
  • Update androidx.exifinterface:exifinterface to 1.3.3.

[1.3.1] - July 28, 2021

  • Update Jetpack Compose to 1.0.0. Huge congrats to the Compose team on the stable release!
  • Update androidx.appcompat:appcompat-resources to 1.3.1.

[1.3.0] - July 10, 2021

  • New: Add support for Jetpack Compose. It's based on Accompanist's Coil integration, but has a number of changes. Check out the docs for more info.
  • Add allowConversionToBitmap to enable/disable the automatic bitmap conversion for Transformations. (#775)
  • Add enforceMinimumFrameDelay to ImageDecoderDecoder and GifDecoder to enable rewriting a GIF's frame delay if it's below a threshold. (#783)
    • This is disabled by default, but will be enabled by default in a future release.
  • Add support for enabling/disabling an ImageLoader's internal network observer. (#741)
  • Fix the density of bitmaps decoded by BitmapFactoryDecoder. (#776)
  • Fix Licensee not finding Coil's licence url. (#774)
  • Update androidx.core:core-ktx to 1.6.0.

[1.2.2] - June 4, 2021

  • Fix race condition while converting a drawable with shared state to a bitmap. (#771)
  • Fix ImageLoader.Builder.fallback setting the error drawable instead of the fallback drawable.
  • Fix incorrect data source returned by ResourceUriFetcher. (#770)
  • Fix log check for no available file descriptors on API 26 and 27.
  • Fix incorrect version check for platform vector drawable support. (#751)
  • Update Kotlin (1.5.10).
  • Update Coroutines (1.5.0).
  • Update androidx.appcompat:appcompat-resources to 1.3.0.
  • Update androidx.core:core-ktx to 1.5.0.

[1.2.1] - April 27, 2021

  • Fix VideoFrameUriFetcher attempting to handle http/https URIs. (#734

[1.2.0] - April 12, 2021

  • Important: Use an SVG's view bounds to calculate its aspect ratio in SvgDecoder. (#688)
  • Previously, SvgDecoder used an SVG's width/height elements to determine its aspect ratio, however this doesn't correctly follow the SVG specification.
  • To revert to the old behaviour set useViewBoundsAsIntrinsicSize = false when constructing your SvgDecoder.
  • New: Add VideoFrameDecoder to support decoding video frames from any source. (#689)
  • New: Support automatic SVG detection using the source's contents instead of just the MIME type. (#654)
  • New: Support sharing resources using ImageLoader.newBuilder(). (#653)
  • Importantly, this enables sharing memory caches between ImageLoader instances.
  • New: Add support for animated image transformations using AnimatedTransformation. (#659)
  • New: Add support for start/end callbacks for animated drawables. (#676)

  • Fix parsing EXIF data for HEIF/HEIC files. (#664)
  • Fix not using the EmptyBitmapPool implementation if bitmap pooling is disabled. (#638)
  • Without this fix bitmap pooling was still disabled properly, however it used a more heavyweight BitmapPool implementation.
  • Fix case where MovieDrawable.getOpacity would incorrectly return transparent. (#682)
  • Guard against the default temporary directory not existing. (#683)

  • Build using the JVM IR backend. (#670)
  • Update Kotlin (1.4.32).
  • Update Coroutines (1.4.3).
  • Update OkHttp (3.12.13).
  • Update androidx.lifecycle:lifecycle-common-java8 to 2.3.1.

[1.1.1] - January 11, 2021

  • Fix a case where ViewSizeResolver.size could throw an IllegalStateException due to resuming a coroutine more than once.
  • Fix HttpFetcher blocking forever if called from the main thread.
    • Requests that are forced to execute on the main thread using ImageRequest.dispatcher(Dispatchers.Main.immediate) will fail with a NetworkOnMainThreadException unless ImageRequest.networkCachePolicy is set to CachePolicy.DISABLED or CachePolicy.WRITE_ONLY.
  • Rotate video frames from VideoFrameFetcher if the video has rotation metadata.
  • Update Kotlin (1.4.21).
  • Update Coroutines (1.4.2).
  • Update Okio (2.10.0).
  • Update androidx.exifinterface:exifinterface (1.3.2).

[1.1.0] - November 24, 2020

  • Important: Change the CENTER and MATRIX ImageView scale types to resolve to OriginalSize. (#587)
    • This change only affects the implicit size resolution algorithm when the request's size isn't specified explicitly.
    • This change was made to ensure that the visual result of an image request is consistent with ImageView.setImageResource/ImageView.setImageURI. To revert to the old behaviour set a ViewSizeResolver when constructing your request.
  • Important: Return the display size from ViewSizeResolver if the view's layout param is WRAP_CONTENT. (#562)
    • Previously, we would only return the display size if the view has been fully laid out. This change makes the typical behaviour more consistent and intuitive.
  • Add the ability to control alpha pre-multiplication. (#569)
  • Support preferring exact intrinsic size in CrossfadeDrawable. (#585)
  • Check for the full GIF header including version. (#564)
  • Add an empty bitmap pool implementation. (#561)
  • Make EventListener.Factory a functional interface. (#575)
  • Stabilize EventListener. (#574)
  • Add String overload for ImageRequest.Builder.placeholderMemoryCacheKey.
  • Add @JvmOverloads to the ViewSizeResolver constructor.
  • Fix: Mutate start/end drawables in CrossfadeDrawable. (#572)
  • Fix: Fix GIF not playing on second load. (#577)
  • Update Kotlin (1.4.20) and migrate to the kotlin-parcelize plugin.
  • Update Coroutines (1.4.1).

[1.0.0] - October 22, 2020

Changes since 0.13.0: - Add Context.imageLoader extension function. (#534) - Add ImageLoader.executeBlocking extension function. (#537) - Don't shutdown previous singleton image loader if replaced. (#533)

Changes since 1.0.0-rc3: - Fix: Guard against missing/invalid ActivityManager. (#541) - Fix: Allow OkHttp to cache unsuccessful responses. (#551) - Update Kotlin to 1.4.10. - Update Okio to 2.9.0. - Update androidx.exifinterface:exifinterface to 1.3.1.

[1.0.0-rc3] - September 21, 2020

  • Revert using the -Xjvm-default=all compiler flag due to instability.
    • This is a source compatible, but binary incompatible change from previous release candidate versions.
  • Add Context.imageLoader extension function. (#534)
  • Add ImageLoader.executeBlocking extension function. (#537)
  • Don't shutdown previous singleton image loader if replaced. (#533)
  • Update AndroidX dependencies:
    • androidx.exifinterface:exifinterface -> 1.3.0

[1.0.0-rc2] - September 3, 2020

  • This release requires Kotlin 1.4.0 or above.
  • All the changes present in 0.13.0.
  • Depend on the base Kotlin stdlib instead of stdlib-jdk8.

[0.13.0] - September 3, 2020

  • Important: Launch the Interceptor chain on the main thread by default. (#513)
    • This largely restores the behaviour from 0.11.0 and below where the memory cache would be checked synchronously on the main thread.
    • To revert to using the same behaviour as 0.12.0 where the memory cache is checked on ImageRequest.dispatcher, set ImageLoader.Builder.launchInterceptorChainOnMainThread(false).
    • See launchInterceptorChainOnMainThread for more information.

  • Fix: Fix potential memory leak if request is started on a ViewTarget in a detached fragment. (#518)
  • Fix: Use ImageRequest.context to load resource URIs. (#517)
  • Fix: Fix race condition that could cause subsequent requests to not be saved to the disk cache. (#510)
  • Fix: Use blockCountLong and blockSizeLong on API 18.

  • Make ImageLoaderFactory a fun interface.
  • Add ImageLoader.Builder.addLastModifiedToFileCacheKey which allows you to enable/disable adding the last modified timestamp to the memory cache key for an image loaded from a File.

  • Update Kotlin to 1.4.0.
  • Update Coroutines to 1.3.9.
  • Update Okio to 2.8.0.

[1.0.0-rc1] - August 18, 2020

  • This release requires Kotlin 1.4.0 or above.
  • Update Kotlin to 1.4.0 and enable -Xjvm-default=all.
    • See here for how to enable -Xjvm-default=all in your build file.
    • This generates Java 8 default methods for default Kotlin interface methods.
  • Remove all existing deprecated methods in 0.12.0.
  • Update Coroutines to 1.3.9.

[0.12.0] - August 18, 2020

  • Breaking: LoadRequest and GetRequest have been replaced with ImageRequest:
    • ImageLoader.execute(LoadRequest) -> ImageLoader.enqueue(ImageRequest)
    • ImageLoader.execute(GetRequest) -> ImageLoader.execute(ImageRequest)
    • ImageRequest implements equals/hashCode.
  • Breaking: A number of classes were renamed and/or changed package:
    • coil.request.RequestResult -> coil.request.ImageResult
    • coil.request.RequestDisposable -> coil.request.Disposable
    • coil.bitmappool.BitmapPool -> coil.bitmap.BitmapPool
    • coil.DefaultRequestOptions -> coil.request.DefaultRequestOptions
  • Breaking: SparseIntArraySet has been removed from the public API.
  • Breaking: TransitionTarget no longer implements ViewTarget.
  • Breaking: ImageRequest.Listener.onSuccess's signature has changed to return an ImageResult.Metadata instead of just a DataSource.
  • Breaking: Remove support for LoadRequest.aliasKeys. This API is better handled with direct read/write access to the memory cache.

  • Important: Values in the memory cache are no longer resolved synchronously (if called from the main thread).
    • This change was also necessary to support executing Interceptors on a background dispatcher.
    • This change also moves more work off the main thread, improving performance.
  • Important: Mappers are now executed on a background dispatcher. As a side effect, automatic bitmap sampling is no longer automatically supported. To achieve the same effect, use the MemoryCache.Key of a previous request as the placeholderMemoryCacheKey of the subsequent request. See here for an example.
    • The placeholderMemoryCacheKey API offers more freedom as you can "link" two image requests with different data (e.g. different URLs for small/large images).
  • Important: Coil's ImageView extension functions have been moved from the coil.api package to the coil package.
    • Use find + replace to refactor import coil.api.load -> import coil.load. Unfortunately, it's not possible to use Kotlin's ReplaceWith functionality to replace imports.
  • Important: Use standard crossfade if drawables are not the same image.
  • Important: Prefer immutable bitmaps on API 24+.
  • Important: MeasuredMapper has been deprecated in favour of the new Interceptor interface. See here for an example of how to convert a MeasuredMapper into an Interceptor.
    • Interceptor is a much less restrictive API that allows for a wider range of custom logic.
  • Important: ImageRequest.data is now not null. If you create an ImageRequest without setting its data it will return NullRequestData as its data.

  • New: Add support for direct read/write access to an ImageLoader's MemoryCache. See the docs for more information.
  • New: Add support for Interceptors. See the docs for more information. Coil's Interceptor design is heavily inspired by OkHttp's!
  • New: Add the ability to enable/disable bitmap pooling using ImageLoader.Builder.bitmapPoolingEnabled.
    • Bitmap pooling is most effective on API 23 and below, but may still be benificial on API 24 and up (by eagerly calling Bitmap.recycle).
  • New: Support thread interruption while decoding.

  • Fix parsing multiple segments in content-type header.
  • Rework bitmap reference counting to be more robust.
  • Fix WebP decoding on API < 19 devices.
  • Expose FetchResult and DecodeResult in the EventListener API.

  • Compile with SDK 30.
  • Update Coroutines to 1.3.8.
  • Update OkHttp to 3.12.12.
  • Update Okio to 2.7.0.
  • Update AndroidX dependencies:
    • androidx.appcompat:appcompat-resources -> 1.2.0
    • androidx.core:core-ktx -> 1.3.1

[0.11.0] - May 14, 2020

  • Breaking: This version removes all existing deprecated functions.
    • This enables removing Coil's ContentProvider so it doesn't run any code at app startup.
  • Breaking: Convert SparseIntArraySet.size to a val. (#380)
  • Breaking: Move Parameters.count() to an extension function. (#403)
  • Breaking: Make BitmapPool.maxSize an Int. (#404)

  • Important: Make ImageLoader.shutdown() optional (similar to OkHttpClient). (#385)

  • Fix: Fix AGP 4.1 compatibility. (#386)
  • Fix: Fix measuring GONE views. (#397)

  • Reduce the default memory cache size to 20%. (#390)
    • To restore the existing behaviour set ImageLoaderBuilder.availableMemoryPercentage(0.25) when creating your ImageLoader.
  • Update Coroutines to 1.3.6.
  • Update OkHttp to 3.12.11.

[0.10.1] - April 26, 2020

  • Fix OOM when decoding large PNGs on API 23 and below. (#372).
    • This disables decoding EXIF orientation for PNG files. PNG EXIF orientation is very rarely used and reading PNG EXIF data (even if it's empty) requires buffering the entire file into memory, which is bad for performance.
  • Minor Java compatibility improvements to SparseIntArraySet.

  • Update Okio to 2.6.0.

[0.10.0] - April 20, 2020

Highlights

  • This version deprecates most of the DSL API in favour of using the builders directly. Here's what the change looks like:

    // 0.9.5 (old)
    val imageLoader = ImageLoader(context) {
        bitmapPoolPercentage(0.5)
        crossfade(true)
    }
    
    val disposable = imageLoader.load(context, "https://www.example.com/image.jpg") {
        target(imageView)
    }
    
    val drawable = imageLoader.get("https://www.example.com/image.jpg") {
        size(512, 512)
    }
    
    // 0.10.0 (new)
    val imageLoader = ImageLoader.Builder(context)
        .bitmapPoolPercentage(0.5)
        .crossfade(true)
        .build()
    
    val request = LoadRequest.Builder(context)
        .data("https://www.example.com/image.jpg")
        .target(imageView)
        .build()
    val disposable = imageLoader.execute(request)
    
    val request = GetRequest.Builder(context)
        .data("https://www.example.com/image.jpg")
        .size(512, 512)
        .build()
    val drawable = imageLoader.execute(request).drawable
    
    • If you're using the io.coil-kt:coil artifact, you can call Coil.execute(request) to execute the request with the singleton ImageLoader.
  • ImageLoaders now have a weak reference memory cache that tracks weak references to images once they're evicted from the strong reference memory cache.

    • This means an image will always be returned from an ImageLoader's memory cache if there's still a strong reference to it.
    • Generally, this should make the memory cache much more predictable and increase its hit rate.
    • This behaviour can be enabled/disabled with ImageLoaderBuilder.trackWeakReferences.
  • Add a new artifact, io.coil-kt:coil-video, to decode specific frames from a video file. Read more here.

  • Add a new EventListener API for tracking metrics.

  • Add ImageLoaderFactory which can be implemented by your Application to simplify singleton initialization.


Full Release Notes

  • Important: Deprecate DSL syntax in favour of builder syntax. (#267)
  • Important: Deprecate Coil and ImageLoader extension functions. (#322)
  • Breaking: Return sealed RequestResult type from ImageLoader.execute(GetRequest). (#349)
  • Breaking: Rename ExperimentalCoil to ExperimentalCoilApi. Migrate from @Experimental to @RequiresOptIn. (#306)
  • Breaking: Replace CoilLogger with Logger interface. (#316)
  • Breaking: Rename destWidth/destHeight to dstWidth/dstHeight. (#275)
  • Breaking: Re-arrange MovieDrawable's constructor params. (#272)
  • Breaking: Request.Listener's methods now receive the full Request object instead of just its data.
  • Breaking: GetRequestBuilder now requires a Context in its constructor.
  • Breaking: Several properties on Request are now nullable.
  • Behaviour change: Include parameter values in the cache key by default. (#319)
  • Behaviour change: Slightly adjust Request.Listener.onStart() timing to be called immediately after Target.onStart(). (#348)

  • New: Add WeakMemoryCache implementation. (#295)
  • New: Add coil-video to support decoding video frames. (#122)
  • New: Introduce EventListener. (#314)
  • New: Introduce ImageLoaderFactory. (#311)
  • New: Support animated HEIF image sequences on Android 11. (#297)
  • New: Improve Java compatibility. (#262)
  • New: Support setting a default CachePolicy. (#307)
  • New: Support setting a default Bitmap.Config. (#342)
  • New: Add ImageLoader.invalidate(key) to clear a single memory cache item (#55)
  • New: Add debug logs to explain why a cached image is not reused. (#346)
  • New: Support error and fallback drawables for get requests.

  • Fix: Fix memory cache miss when Transformation reduces input bitmap's size. (#357)
  • Fix: Ensure radius is below RenderScript max in BlurTransformation. (#291)
  • Fix: Fix decoding high colour depth images. (#358)
  • Fix: Disable ImageDecoderDecoder crash work-around on Android 11 and above. (#298)
  • Fix: Fix failing to read EXIF data on pre-API 23. (#331)
  • Fix: Fix incompatibility with Android R SDK. (#337)
  • Fix: Only enable inexact size if ImageView has a matching SizeResolver. (#344)
  • Fix: Allow cached images to be at most one pixel off requested size. (#360)
  • Fix: Skip crossfade transition if view is not visible. (#361)

  • Deprecate CoilContentProvider. (#293)
  • Annotate several ImageLoader methods with @MainThread.
  • Avoid creating a LifecycleCoroutineDispatcher if the lifecycle is currently started. (#356)
  • Use full package name for OriginalSize.toString().
  • Preallocate when decoding software bitmap. (#354)

  • Update Kotlin to 1.3.72.
  • Update Coroutines to 1.3.5.
  • Update OkHttp to 3.12.10.
  • Update Okio to 2.5.0.
  • Update AndroidX dependencies:
    • androidx.exifinterface:exifinterface -> 1.2.0

[0.9.5] - February 6, 2020

  • Fix: Ensure a view is attached before checking if it is hardware accelerated. This fixes a case where requesting a hardware bitmap could miss the memory cache.

  • Update AndroidX dependencies:
    • androidx.core:core-ktx -> 1.2.0

[0.9.4] - February 3, 2020

  • Fix: Respect aspect ratio when downsampling in ImageDecoderDecoder. Thanks @zhanghai.

  • Previously bitmaps would be returned from the memory cache as long as their config was greater than or equal to the config specified in the request. For example, if you requested an ARGB_8888 bitmap, it would be possible to have a RGBA_F16 bitmap returned to you from the memory cache. Now, the cached config and the requested config must be equal.
  • Make scale and durationMillis public in CrossfadeDrawable and CrossfadeTransition.

[0.9.3] - February 1, 2020

  • Fix: Translate child drawable inside ScaleDrawable to ensure it is centered.
  • Fix: Fix case where GIFs and SVGs would not fill bounds completely.

  • Defer calling HttpUrl.get() to background thread.
  • Improve BitmapFactory null bitmap error message.
  • Add 3 devices to hardware bitmap blacklist. (#264)

  • Update AndroidX dependencies:
    • androidx.lifecycle:lifecycle-common-java8 -> 2.2.0

[0.9.2] - January 19, 2020

  • Fix: Fix decoding GIFs on pre-API 19. Thanks @mario.
  • Fix: Fix rasterized vector drawables not being marked as sampled.
  • Fix: Throw exception if Movie dimensions are <= 0.
  • Fix: Fix CrossfadeTransition not being resumed for a memory cache event.
  • Fix: Prevent returning hardware bitmaps to all target methods if disallowed.
  • Fix: Fix MovieDrawable not positioning itself in the center of its bounds.

  • Remove automatic scaling from CrossfadeDrawable.
  • Make BitmapPool.trimMemory public.
  • Wrap AnimatedImageDrawable in a ScaleDrawable to ensure it fills its bounds.
  • Add @JvmOverloads to RequestBuilder.setParameter.
  • Set an SVG's view box to its size if the view box is not set.
  • Pass state and level changes to CrossfadeDrawable children.

  • Update OkHttp to 3.12.8.

[0.9.1] - December 30, 2019

  • Fix: Fix crash when calling LoadRequestBuilder.crossfade(false).

[0.9.0] - December 30, 2019

  • Breaking: Transformation.transform now includes a Size parameter. This is to support transformations that change the size of the output Bitmap based on the size of the Target. Requests with transformations are now also exempt from image sampling.
  • Breaking: Transformations are now applied to any type of Drawable. Before, Transformations would be skipped if the input Drawable was not a BitmapDrawable. Now, Drawables are rendered to a Bitmap before applying the Transformations.
  • Breaking: Passing null data to ImageLoader.load is now treated as an error and calls Target.onError and Request.Listener.onError with a NullRequestDataException. This change was made to support setting a fallback drawable if data is null. Previously the request was silently ignored.
  • Breaking: RequestDisposable.isDisposed is now a val.

  • New: Support for custom transitions. See here for more info. Transitions are marked as experimental as the API is incubating.
  • New: Add RequestDisposable.await to support suspending while a LoadRequest is in progress.
  • New: Support setting a fallback drawable when request data is null.
  • New: Add Precision. This makes the size of the output Drawable exact while enabling scaling optimizations for targets that support scaling (e.g. ImageViewTarget). See its documentation for more information.
  • New: Add RequestBuilder.aliasKeys to support matching multiple cache keys.

  • Fix: Make RequestDisposable thread safe.
  • Fix: RoundedCornersTransformation now crops to the size of the target then rounds the corners.
  • Fix: CircleCropTransformation now crops from the center.
  • Fix: Add several devices to the hardware bitmap blacklist.
  • Fix: Preserve aspect ratio when converting a Drawable to a Bitmap.
  • Fix: Fix possible memory cache miss with Scale.FIT.
  • Fix: Ensure Parameters iteration order is deterministic.
  • Fix: Defensive copy when creating Parameters and ComponentRegistry.
  • Fix: Ensure RealBitmapPool's maxSize >= 0.
  • Fix: Show the start drawable if CrossfadeDrawable is not animating or done.
  • Fix: Adjust CrossfadeDrawable to account for children with undefined intrinsic size.
  • Fix: Fix MovieDrawable not scaling properly.

  • Update Kotlin to 1.3.61.
  • Update Kotlin Coroutines to 1.3.3.
  • Update Okio to 2.4.3.
  • Update AndroidX dependencies:
    • androidx.exifinterface:exifinterface -> 1.1.0

[0.8.0] - October 22, 2019

  • Breaking: SvgDrawable has been removed. Instead, SVGs are now prerendered to BitmapDrawables by SvgDecoder. This makes SVGs significantly less expensive to render on the main thread. Also SvgDecoder now requires a Context in its constructor.
  • Breaking: SparseIntArraySet extension functions have moved to the coil.extension package.

  • New: Support setting per-request network headers. See here for more info.
  • New: Add new Parameters API to support passing custom data through the image pipeline.
  • New: Support individual corner radii in RoundedCornersTransformation. Thanks @khatv911.
  • New: Add ImageView.clear() to support proactively freeing resources.
  • New: Support loading resources from other packages.
  • New: Add subtractPadding attribute to ViewSizeResolver to enable/disable subtracting a view's padding when measuring.
  • New: Improve HttpUrlFetcher MIME type detection.
  • New: Add Animatable2Compat support to MovieDrawable and CrossfadeDrawable.
  • New: Add RequestBuilder<*>.repeatCount to set the repeat count for a GIF.
  • New: Add BitmapPool creation to the public API.
  • New: Annotate Request.Listener methods with @MainThread.

  • Fix: Make CoilContentProvider visible for testing.
  • Fix: Include night mode in the resource cache key.
  • Fix: Work around ImageDecoder native crash by temporarily writing the source to disk.
  • Fix: Correctly handle contact display photo uris.
  • Fix: Pass tint to CrossfadeDrawable's children.
  • Fix: Fix several instances of not closing sources.
  • Fix: Add a blacklist of devices with broken/incomplete hardware bitmap implementations.

  • Compile against SDK 29.
  • Update Kotlin Coroutines to 1.3.2.
  • Update OkHttp to 3.12.6.
  • Update Okio to 2.4.1.
  • Change appcompat-resources from compileOnly to implementation for coil-base.

[0.7.0] - September 8, 2019

  • Breaking: ImageLoaderBuilder.okHttpClient(OkHttpClient.Builder.() -> Unit) is now ImageLoaderBuilder.okHttpClient(() -> OkHttpClient). The initializer is also now called lazily on a background thread. If you set a custom OkHttpClient you must set OkHttpClient.cache to enable disk caching. If you don't set a custom OkHttpClient, Coil will create the default OkHttpClient which has disk caching enabled. The default Coil cache can be created using CoilUtils.createDefaultCache(context). e.g.:
val imageLoader = ImageLoader(context) {
    okHttpClient {
        OkHttpClient.Builder()
            .cache(CoilUtils.createDefaultCache(context))
            .build()
    }
}
  • Breaking: Fetcher.key no longer has a default implementation.
  • Breaking: Previously, only the first applicable Mapper would be called. Now, all applicable Mappers will be called. No API changes.
  • Breaking: Minor named parameter renaming: url -> uri, factory -> initializer.

  • New: coil-svg artifact, which has an SvgDecoder that supports automatically decoding SVGs. Powered by AndroidSVG. Thanks @rharter.
  • New: load(String) and get(String) now accept any of the supported Uri schemes. e.g. You can now do imageView.load("file:///path/to/file.jpg").
  • New: Refactor ImageLoader to use Call.Factory instead of OkHttpClient. This allows lazy initialization of the networking resources using ImageLoaderBuilder.okHttpClient { OkHttpClient() }. Thanks @ZacSweers.
  • New: RequestBuilder.decoder to explicitly set the decoder for a request.
  • New: ImageLoaderBuilder.allowHardware to enable/disable hardware bitmaps by default for an ImageLoader.
  • New: Support software rendering in ImageDecoderDecoder.

  • Fix: Multiple bugs with loading vector drawables.
  • Fix: Support WRAP_CONTENT View dimensions.
  • Fix: Support parsing EXIF data longer than 8192 bytes.
  • Fix: Don't stretch drawables with different aspect ratios when crossfading.
  • Fix: Guard against network observer failing to register due to exception.
  • Fix: Fix divide by zero error in MovieDrawable. Thanks @R12rus.
  • Fix: Support nested Android asset files. Thanks @JaCzekanski.
  • Fix: Guard against running out of file descriptors on Android O and O_MR1.
  • Fix: Don't crash when disabling memory cache. Thanks @hansenji.
  • Fix: Ensure Target.cancel is always called from the main thread.

  • Update Kotlin to 1.3.50.
  • Update Kotlin Coroutines to 1.3.0.
  • Update OkHttp to 3.12.4.
  • Update Okio to 2.4.0.
  • Update AndroidX dependencies to the latest stable versions:
    • androidx.appcompat:appcompat -> 1.1.0
    • androidx.core:core-ktx -> 1.1.0
    • androidx.lifecycle:lifecycle-common-java8 -> 2.1.0
  • Replace appcompat with appcompat-resources as an optional compileOnly dependency. appcompat-resources is a much smaller artifact.

[0.6.1] - August 16, 2019

  • New: Add transformations(List<Transformation>) to RequestBuilder.
  • Fix: Add the last modified date to the cache key for file uris.
  • Fix: Ensure View dimensions are evaluated to at least 1px.
  • Fix: Clear MovieDrawable's canvas between frames.
  • Fix: Open assets correctly.

[0.6.0] - August 12, 2019

  • Initial release.