Changelog¶
[3.3.0] - July 22, 2025¶
- New: Introduce a new API to limit
MemoryCache.maxSizeon Android while the app is backgrounded.- If
ImageLoader.Builder.memoryCacheMaxSizePercentWhileInBackgroundis set, theImageLoader's memory cache will be limited to a percent of its max size while the app is backgrounded. This setting is currently disabled by default. - Images will be trimmed from the memory cache to reach the limited max size when the app is backgrounded, however the memory cache's weak references to recently trimmed images are unaffected. This means if an image is currently referenced elsewhere (e.g.
AsyncImage,ImageView, etc.) it will still be present in the memory cache. - This API is useful to reduce background memory usage, keep your app from being killed earlier, and help reduce memory pressure on your users' devices.
- If
- New: Add an
Svg.Parserargument toSvgDecoder.- This enables using custom SVG parsers if the default SVG parser doesn't meet your needs.
- Add a
densityargument toSvgDecoderto support providing a custom density multiplier. - Add
Uri.Builderto support copying and modifyingUris. - Add
ImageLoader.Builder.mainCoroutineContextto support overriding Coil'sDispatchers.main.immediateusage in tests. - Fix
CrossfadePainter.intrinsicSizechanging when thestartimage is dereferenced at the end of the animation. This aligns with the behaviour ofCrossfadeDrawable. - Fix
ImageLoaders.executeBlockingbeing inaccessible from Java. - Use
kotlinx.io's Okio interop module incoil-network-ktor3. - Update
kotlinx-datetimeto0.7.1.- This release includes binary incompatible changes that only affect the
coil-network-cache-controlmodule. See here for more info.
- This release includes binary incompatible changes that only affect the
- Update Kotlin to 2.2.0.
- Update Compose to 1.8.2.
- Update Okio to 3.15.0.
- Update Skiko to 0.9.4.2.
[3.2.0] - May 13, 2025¶
Changes since 3.1.0:
- Important:
coil-composeandcoil-compose-corenow require Java 11 bytecode due to Compose1.8.0requiring it. See here for how to enable it. - Change
AsyncImagePreviewHandler's functional constructor to returnAsyncImagePainter.State.Successinstead ofAsyncImagePainter.State.Loading. - Fix cancellation in
ConstraintsSizeResolver#size(). - Fix warning for missing
PlatformContextwhen building with R8. - Fix
FakeImageLoaderEnginenot settingTransition.Factory.NONEwhen the defaultFakeImageLoaderEngineresponse is returned. - Remove experimental annotation from
ColorImage. - Parse network headers lazily in
CacheControlCacheStrategy. - Refactor
CircleCropTransformationandRoundedCornersTransformationto share common code. - Fall back to using
BitmapFactoryinternally ifExifOrientationStrategyis notRESPECT_PERFORMANCE. - Update Kotlin to 2.1.20.
- Update Compose to 1.8.0.
- Update Okio to 3.11.0.
- Update Skiko to 0.9.4.
- Update Coroutines to 1.10.2.
- Update
accompanist-drawablepainterto 0.37.3.
Changes since 3.2.0-rc02:
- Fall back to using
BitmapFactoryinternally ifExifOrientationStrategyis notRESPECT_PERFORMANCE. - Update Compose to 1.8.0.
- Update
accompanist-drawablepainterto 0.37.3.
[3.2.0-rc02] - April 26, 2025¶
- Fix image requests failing with
ClosedByteChannelExceptionwhen loading an image withKtorNetworkFetcherFactory(Ktor 3) on non-JVM targets.
[3.2.0-rc01] - April 24, 2025¶
- Important:
coil-composeandcoil-compose-corenow require Java 11 bytecode due to Compose1.8.0requiring it. See here for how to enable it. - Change
AsyncImagePreviewHandler's functional constructor to returnAsyncImagePainter.State.Successinstead ofAsyncImagePainter.State.Loading. - Fix cancellation in
ConstraintsSizeResolver#size(). - Fix warning for missing
PlatformContextwhen building with R8. - Fix
FakeImageLoaderEnginenot settingTransition.Factory.NONEwhen the defaultFakeImageLoaderEngineresponse is returned. - Remove experimental annotation from
ColorImage. - Parse network headers lazily in
CacheControlCacheStrategy. - Refactor
CircleCropTransformationandRoundedCornersTransformationto share common code. - Use
kotlinx.io's Okio interop module incoil-network-ktor2andcoil-network-ktor3. - Update Kotlin to 2.1.20.
- Update Compose to 1.8.0-rc01.
- Update Okio to 3.11.0.
- Update Skiko to 0.9.4.
- Update Coroutines to 1.10.2.
[3.1.0] - February 4, 2025¶
- Improve
AsyncImageperformance.- Runtime performance is improved by 25% to 40% depending on if the composable is being instantiated or reused. Allocations are also reduced by 35% to 48%. More info here.
- Add
ColorImageand deprecateFakeImage.ColorImageis useful for returning a fake value in tests and previews. It solves the same use case asFakeImage, but is more easily accessible incoil-coreinstead ofcoil-test.
- Remove
coil-compose-core's dependency onDispatchers.Main.immedate.- This also fixes a case where
AsyncImagePainterwould not executeImageRequests synchronously in Paparazzi and Roborazzi screenshot tests.
- This also fixes a case where
- Add support for data URIs with the format:
data:[<mediatype>][;base64],<data> - Add
AnimatedImageDecoder.ENCODED_LOOP_COUNTto support using the encoded repeat count in a GIF's metadata. - Add
ExtrastoNetworkRequestto support custom extensions. - Add
DiskCache.Builder.cleanupCoroutineContextand deprecateDiskCache.Builder.cleanupDispatcher. - Add
ImageLoader.Builder.imageDecoderEnabledto optionally disable usingandroid.graphics.ImageDecoderon API 29 and above. - Log a warning if there is no registered
Keyerfor anImageRequest's data type. - Make
CrossfadePainterpublic. - Support
Transformations on all multiplatform targets. - Support 0 as
Expiresheader value inCacheControlCacheStrategy. - Fix
AsyncImage/SubcomposeAsyncImage/rememberAsyncImagenot launching a newImageRequestif itsContentScalechanges to/fromNone. - Update Kotlin to 2.1.10.
- NOTE: This release requires compiling with Kotlin 2.1.0 or greater if you use Kotlin native due to an LLVM update.
- Update Compose to 1.7.3.
- Update
androidx.coreto 1.15.0.
[3.0.4] - November 25, 2024¶
- Fix vector drawables not rendering in the Android Studio preview.
- Fix potential memory cache miss for requests whose size exceeds
maxBitmapSize. - Fix
FakeImagenot rendering on Android. - Fix not launching a new image request when the request's
Transformations change when used withAsyncImage/rememberAsyncImagePainter/SubcomposeAsyncImage. - Fix
ScaleDrawableandCrossfadeDrawablenot respecting tint states. - Allow
ImageDecoderto decode partial image sources. This matches the behavior inBitmapFactory. - Fix
Bitmap.prepareToDraw()not being called after decoding. SvgDecodershould not returnisSampled = truefor non-rasterized images.- Fall back to
Dispatchers.Unconfinedin Compose if an immediate main dispatcher is unavailable. This is only used in preview/test environments. - Update Ktor 2 to
2.3.13.
[3.0.3] - November 14, 2024¶
- Fix setting
ImageRequest.scalebased on anImageView'sScaleType. - Fix edge case where
DiskCachewould not track removal of an entry after deleting its files. - Pass throwable to
Loggerwhen logging errors. - Don't replace
kotlin-stdlib-jdk7andkotlin-stdlib-jdk8withkotlin-stdlib.
[3.0.2] - November 9, 2024¶
- Fix crash when invoking
OkHttpNetworkFetcherFactorywith a customCacheStrategyon Android. - Fix
CacheControlCacheStrategycomputing the age of a cache entry incorrectly. - Fix case where
ImageRequest.bitmapConfigwould only be respected on >= API 28 if it wasARGB_8888orHARDWARE.
[3.0.1] - November 7, 2024¶
- Fix crash when calling
Image.toBitmapwith a hardware bitmap-backedBitmapImage. - Fix
AsyncImageModelEqualityDelegate.Defaultcomparing equality incorrectly for non-ImageRequestmodels.
[3.0.0] - November 4, 2024¶
Coil 3.0.0 is the next major release of Coil with full support for Compose Multiplatform.
For the full list of improvements and important changes in 3.0.0, check out the upgrade guide.
Changes since 3.0.0-rc02:
- Remove remaining deprecated methods.
[3.0.0-rc02] - October 28, 2024¶
For the full list of improvements and important changes in 3.x, check out the upgrade guide. Changes since 3.0.0-rc01:
- Add
BlackholeDecoder. This simplifies disk-cache only preloading. - Add
rememberfunctions forConstraintsSizeResolverandDrawScopeSizeResolver. - Remove
EqualityDelegateas a parameter toAsyncImage. Instead, it should be set throughLocalAsyncImageModelEqualityDelegate. - Fix
AsyncImagenot rendering when parent composable usesIntrinsicSize. - Fix
AsyncImagefilling the available constraints whenAsyncImagePainterhas no child painter. - Fix
rememberAsyncImagePainterrecomposing infinitely when its state is observed due toEqualityDelegatebeing ignored. - Fix parsing
File/Pathpaths with special characters. - Fix using custom
FileSystemimplementations withVideoFrameDecoder. - Update Ktor to
3.0.0. - Update
androidx.annotationto1.9.0.
[3.0.0-rc01] - October 8, 2024¶
For the full list of improvements and important changes in 3.x, check out the upgrade guide. Changes since 3.0.0-alpha10:
- BREAKING Disable
addLastModifiedToFileCacheKeyby default and allow it to be set per request. The behaviour can be reenabled with the same flag. - New: Introduce a new
coil-network-cache-controlartifact, which implementsCache-Controlheader support. - New: Add
scaleToDensityproperty toSvgDecoder.Factory. This property ensure SVGs with intrinsic dimensions are multiplied by the devices density (only supported on Android). - Rename
ExifOrientationPolicytoExifOrientationStrategy. - Remove unshareable images from the
MemoryCacheon get. - Make
ConstraintsSizeResolverpublic. - Stabilize
setSingletonImageLoaderFactory. - Restore optimized JVM I/O functions in
coil-network-ktor3 - Add
pdfto list of mime types. - Update compile sdk to 35.
- Update Kotlin to 2.0.20.
- Update Okio to 3.9.1.
[3.0.0-alpha10] - August 7, 2024¶
- BREAKING: Replace
ImageLoader.Builder.networkObserverEnabledwith aConnectivityCheckerinterface forNetworkFetcher.- To disable the network observer, pass
ConnectivityChecker.ONLINEto the constructor forKtorNetworkFetcherFactory/OkHttpNetworkFetcherFactory.
- To disable the network observer, pass
- New: Support loading Compose Multiplatform resources on all platforms. To load a resource, use
Res.getUri:
- Add
maxBitmapSizeproperty toImageLoaderandImageRequest.- This property defaults to 4096x4096 and provides a safe upper bound for the dimensions of an allocated bitmap. This helps accidentally loading very large images with
Size.ORIGINALand causing an out of memory exception.
- This property defaults to 4096x4096 and provides a safe upper bound for the dimensions of an allocated bitmap. This helps accidentally loading very large images with
- Convert
ExifOrientationPolicyto be an interface to support custom policies. - Fix
Urihandling of Windows file paths. - Remove
@ExperimentalCoilApifrom theImageAPIs. - Update Kotlin to 2.0.10.
[3.0.0-alpha09] - July 23, 2024¶
- BREAKING: Rename the
io.coil-kt.coil3:coil-network-ktorartifact toio.coil-kt.coil3:coil-network-ktor2which depends on Ktor 2.x. Additionally, introduceio.coil-kt.coil3:coil-network-ktor3which depends on Ktor 3.x.wasmJssupport is only available in Ktor 3.x. - New: Add
AsyncImagePainter.restart()to manually restart an image request. - Remove
@ExperimentalCoilApifromNetworkClientand related classes. - Optimize
ImageRequestto avoid unnecessaryExtrasandMapallocations.
[2.7.0] - July 17, 2024¶
- Slightly optimize internal coroutines usage to improve the performance of
ImageLoader.execute,AsyncImage,SubcomposeAsyncImage, andrememberAsyncImagePainter. (#2205) - Fix duplicate network calls for chunked responses. (#2363)
- Update Kotlin to 2.0.0.
- Update Compose UI to 1.6.8.
- Update Okio to 3.9.0.
[3.0.0-alpha08] - July 8, 2024¶
- BREAKING: Rename
ImageRequestandImageLoaderdispatchermethods tocoroutineContext. For instance,ImageRequest.Builder.dispatcheris nowImageRequest.Builder.coroutineContext. This was renamed as the method now accepts anyCoroutineContextand no longer requires aDispatcher. - Fix: Fix
IllegalStateException: Reading a state that was created after the snapshot was taken or in a snapshot that has not yet been appliedwhich could occur due to a race condition.- NOTE: This reintroduces a soft dependency on
Dispatchers.Main.immediate. As a result you should re-add a dependency onkotlinx-coroutines-swingon JVM. If it's not imported thenImageRequests won't be dispatched immediately and will have one frame of delay before setting theImageRequest.placeholderor resolving from the memory cache.
- NOTE: This reintroduces a soft dependency on
[3.0.0-alpha07] - June 26, 2024¶
- BREAKING:
AsyncImagePainterno longer waits foronDrawby default and instead usesSize.ORIGINAL.- This fixes compatibility issues with Roborazzi/Paparazzi and overall improves test reliability.
- To revert back to waiting for
onDraw, setDrawScopeSizeResolveras yourImageRequest.sizeResolver.
- BREAKING: Refactor the multiplatform
ImageAPI. Notably,asCoilImagehas been renamed toasImage. - BREAKING:
AsyncImagePainter.statehas been changed toStateFlow<AsyncImagePainter.State>. UsecollectAsStateto observe its value. This improves performance. - BREAKING:
AsyncImagePainter.imageLoaderandAsyncImagePainter.requesthave been combined intoStateFlow<AsyncImagePainter.Inputs>. UsecollectAsStateto observe its value. This improves performance. - BREAKING: Remove support for
android.resource://example.package.name/drawable/imageURIs as it prevents resource shrinking optimizations.- If you still needs its functionality you can manually include
ResourceUriMapperin your component registry.
- If you still needs its functionality you can manually include
- New: Introduce
AsyncImagePreviewHandlerto support controllingAsyncImagePainter's preview rendering behavior.- Use
LocalAsyncImagePreviewHandlerto override the preview behavior. - As part of this change and other
coil-composeimprovements,AsyncImagePainternow attempts to execute execute theImageRequestby default instead of defaulting to displayingImageRequest.placeholder. Requests that use the network or files are expected to fail in the preview environment, however Android resources should work.
- Use
- New: Support extracting video image by frame index. (#2183)
- New: Support passing
CoroutineContextto anyCoroutineDispatchermethods. (#2241). - New: Support the weak reference memory cache on JS and WASM JS.
- Don't dispatch to
Dispatchers.Main.immediatein Compose. As a side-effect,kotlinx-coroutines-swingno longer needs to be imported on JVM. - Don't call
asyncand create a disposable in Compose to improve performance (thanks @mlykotom!). (#2205) - Fix passing global
ImageLoaderextras toOptions. (#2223) - Fix
crossfade(false)not working on non-Android targets. - Fix VP8X feature flags byte offset (#2199).
- Convert
SvgDecoderon non-Android targets to render to a bitmap instead of render the image at draw-time. This improves performance.- This behavior can be controlled using
SvgDecoder(renderToBitmap).
- This behavior can be controlled using
- Move
ScaleDrawablefromcoil-giftocoil-core. - Update Kotlin to 2.0.0.
- Update Compose to 1.6.11.
- Update Okio to 3.9.0.
- Update Skiko to 0.8.4.
- For the full list of important changes in 3.x, check out the upgrade guide.
[3.0.0-alpha06] - February 29, 2024¶
- Downgrade Skiko to 0.7.93.
- For the full list of important changes in 3.x, check out the upgrade guide.
[3.0.0-alpha05] - February 28, 2024¶
- New: Support the
wasmJstarget. - Create
DrawablePainterandDrawableImageto support drawingImages that aren't backed by aBitmapon non-Android platforms.- The
ImageAPIs are experimental and likely to change between alpha releases.
- The
- Update
ContentPainterModifierto implementModifier.Node. - Fix: Lazily register component callbacks and the network observer on a background thread. This fixes slow initialization that would typically occur on the main thread.
- Fix: Fix
ImageLoader.Builder.placeholder/error/fallbacknot being used byImageRequest. - Update Compose to 1.6.0.
- Update Coroutines to 1.8.0.
- Update Okio to 3.8.0.
- Update Skiko to 0.7.94.
- For the full list of important changes in 3.x, check out the upgrade guide.
[2.6.0] - February 23, 2024¶
- Make
rememberAsyncImagePainter,AsyncImage, andSubcomposeAsyncImagerestartable and skippable. This improves performance by avoiding recomposition unless one of the composable's arguments changes.- Add an optional
modelEqualityDelegateargument torememberAsyncImagePainter,AsyncImage, andSubcomposeAsyncImageto control whether themodelwill trigger a recomposition.
- Add an optional
- Update
ContentPainterModifierto implementModifier.Node. - Fix: Lazily register component callbacks and the network observer on a background thread. This fixes slow initialization that would typically occur on the main thread.
- Fix: Avoid relaunching a new image request in
rememberAsyncImagePainter,AsyncImage, andSubcomposeAsyncImageifImageRequest.listenerorImageRequest.targetchange. - Fix: Don't observe the image request twice in
AsyncImagePainter. - Update Kotlin to 1.9.22.
- Update Compose to 1.6.1.
- Update Okio to 3.8.0.
- Update
androidx.collectionto 1.4.0. - Update
androidx.lifecycleto 2.7.0.
[3.0.0-alpha04] - February 1, 2024¶
- Breaking: Remove
LazyfromOkHttpNetworkFetcherFactoryandKtorNetworkFetcherFactory's public API. - Expose
Call.Factoryinstead ofOkHttpClientinOkHttpNetworkFetcherFactory. - Convert
NetworkResponseBodyto wrap aByteString. - Downgrade Compose to 1.5.12.
- For the full list of important changes, check out the upgrade guide.
[3.0.0-alpha03] - January 20, 2024¶
- Breaking:
coil-networkhas been renamed tocoil-network-ktor. Additionally, there is a newcoil-network-okhttpartifact that depends on OkHttp and doesn't require specifying a Ktor engine.- Depending on which artifact you import you can reference the
Fetcher.Factorymanually usingKtorNetworkFetcherFactoryorOkHttpNetworkFetcherFactory.
- Depending on which artifact you import you can reference the
- Support loading
NSUrlon Apple platforms. - Add
clipToBoundsparameter toAsyncImage. - For the full list of important changes, check out the upgrade guide.
[3.0.0-alpha02] - January 10, 2024¶
- Breaking:
coil-gif,coil-network,coil-svg, andcoil-video's packages have been updated so all their classes are part ofcoil.gif,coil.network,coil.svg, andcoil.videorespectively. This helps avoid class name conflicts with other artifacts. - Breaking:
ImageDecoderDecoderhas been renamed toAnimatedImageDecoder. - New:
coil-gif,coil-network,coil-svg, andcoil-video's components are now automatically added to eachImageLoader'sComponentRegistry.- To be clear, unlike
3.0.0-alpha01you do not need to manually addNetworkFetcher.Factory()to yourComponentRegistry. Simply importingio.coil-kt.coil3:coil-network:[version]and a Ktor engine is enough to load network images. - It's safe to also add these components to
ComponentRegistrymanually. Any manually added components take precedence over components that are added automatically. - If preferred, this behaviour can be disabled using
ImageLoader.Builder.serviceLoaderEnabled(false).
- To be clear, unlike
- New: Support
coil-svgon all platforms. It's backed by AndroidSVG on Android and SVGDOM on non-Android platforms. - Coil now uses Android's
ImageDecoderAPI internally, which has performance benefits when decoding directly from a file, resource, or content URI. - Fix: Multiple
coil3.Uriparsing fixes. - For the full list of important changes, check out the upgrade guide.
[3.0.0-alpha01] - December 30, 2023¶
- New: Compose Multiplatform support. Coil is now a Kotlin Multiplatform library that supports Android, JVM, iOS, macOS, and Javascript.
- Coil's Maven coordinates were updated to
io.coil-kt.coil3and its imports were updated tocoil3. This allows Coil 3 to run side by side with Coil 2 without binary compatibility issues. For example,io.coil-kt:coil:[version]is nowio.coil-kt.coil3:coil:[version]. - The
coil-baseandcoil-compose-baseartifacts were renamed tocoil-coreandcoil-compose-corerespectively to align with the naming conventions used by Coroutines, Ktor, and AndroidX. - For the full list of important changes, check out the upgrade guide.
[2.5.0] - October 30, 2023¶
- New: Add
MediaDataSourceFetcher.Factoryto support decodingMediaDataSourceimplementations incoil-video. (#1795) - Add the
SHIFT6mdevice to the hardware bitmap blocklist. (#1812) - Fix: Guard against painters that return a size with one unbounded dimension. (#1826)
- Fix: Disk cache load fails after
304 Not Modifiedwhen cached headers include non-ASCII characters. (#1839) - Fix:
FakeImageEnginenot updating the interceptor chain's request. (#1905) - Update compile SDK to 34.
- Update Kotlin to 1.9.10.
- Update Coroutines to 1.7.3.
- Update
accompanist-drawablepainterto 0.32.0. - Update
androidx.annotationto 1.7.0. - Update
androidx.compose.foundationto 1.5.4. - Update
androidx.coreto 1.12.0. - Update
androidx.exifinterface:exifinterfaceto 1.3.6. - Update
androidx.lifecycleto 2.6.2. - Update
com.squareup.okhttp3to 4.12.0. - Update
com.squareup.okioto 3.6.0.
[2.4.0] - May 21, 2023¶
- Rename
DiskCacheget/edittoopenSnapshot/openEditor. - Don't automatically convert
ColorDrawabletoColorPainterinAsyncImagePainter. - Annotate simple
AsyncImageoverloads with@NonRestartableComposable. - Fix: Call
Context.cacheDirlazily inImageSource. - Fix: Fix publishing
coil-bom. - Fix: Fix always setting bitmap config to
ARGB_8888if hardware bitmaps are disabled. - Update Kotlin to 1.8.21.
- Update Coroutines to 1.7.1.
- Update
accompanist-drawablepainterto 0.30.1. - Update
androidx.compose.foundationto 1.4.3. - Update
androidx.profileinstaller:profileinstallerto 1.3.1. - Update
com.squareup.okhttp3to 4.11.0.
[2.3.0] - March 25, 2023¶
- New: Introduce a new
coil-testartifact, which includesFakeImageLoaderEngine. This class is useful for hardcoding image loader responses to ensure consistent and synchronous (from the main thread) responses in tests. See here for more info. - New: Add baseline profiles to
coil-base(child module ofcoil) andcoil-compose-base(child module ofcoil-compose).- This improves Coil's runtime performance and should offer better frame timings depending on how Coil is used in your app.
- Fix: Fix parsing
file://URIs with encoded data. #1601 - Fix:
DiskCachenow properly computes its maximum size if passed a directory that does not exist. #1620 - Make
Coil.resetpublic API. #1506 - Enable Java default method generation. #1491
- Update Kotlin to 1.8.10.
- Update
accompanist-drawablepainterto 0.30.0. - Update
androidx.annotationto 1.6.0. - Update
androidx.appcompat:appcompat-resourcesto 1.6.1. - Update
androidx.compose.foundationto 1.4.0. - Update
androidx.coreto 1.9.0. - Update
androidx.exifinterface:exifinterfaceto 1.3.6. - Update
androidx.lifecycleto 2.6.1. - Update
okioto 3.3.0.
[2.2.2] - October 1, 2022¶
- Ensure an image loader is fully initialized before registering its system callbacks. #1465
- Set the preferred bitmap config in
VideoFrameDecoderon API 30+ to avoid banding. #1487 - Fix parsing paths containing
#inFileUriMapper. #1466 - Fix reading responses with non-ascii headers from the disk cache. #1468
- Fix decoding videos inside asset subfolders. #1489
- Update
androidx.annotationto 1.5.0.
[2.2.1] - September 8, 2022¶
- Fix:
RoundedCornersTransformationnow properly scales theinputbitmap. - Remove dependency on the
kotlin-parcelizeplugin. - Update compile SDK to 33.
- Downgrade
androidx.appcompat:appcompat-resourcesto 1.4.2 to work around #1423.
[2.2.0] - August 16, 2022¶
- New: Add
ImageRequest.videoFramePercenttocoil-videoto support specifying the video frame as a percent of the video's duration. - New: Add
ExifOrientationPolicyto configure howBitmapFactoryDecodertreats EXIF orientation data. - Fix: Don't throw an exception in
RoundedCornersTransformationif 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-drawablepainterto 0.25.1. - Update
androidx.annotationto 1.4.0. - Update
androidx.appcompat:appcompat-resourcesto 1.5.0. - Update
androidx.coreto 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
AsyncImageincoil-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
DiskCacheAPI.- Use
ImageLoader.Builder.diskCacheandDiskCache.Builderto configure the disk cache. - You should not use OkHttp's
Cachewith Coil 2.0. See here for more info. Cache-Controland other cache headers are still supported - exceptVaryheaders, 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.
- Use
- The minimum supported API is now 21.
ImageRequest's defaultScaleis nowScale.FIT.- This was changed to make
ImageRequest.scaleconsistent with other classes that have a defaultScale. - Requests with an
ImageViewTargetstill have theirScaleauto-detected.
- This was changed to make
- Rework the image pipeline classes:
Mapper,Fetcher, andDecoderhave been refactored to be more flexible.Fetcher.keyhas been replaced with a newKeyerinterface.Keyercreates the cache key from the input data.- Add
ImageSource, which allowsDecoders to readFiles directly using Okio's file system API.
- Rework the Jetpack Compose integration:
rememberImagePainterandImagePainterhave been renamed torememberAsyncImagePainterandAsyncImagePainterrespectively.- 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
NullPointerExceptionimmediately. Kotlin's compile-time null safety guards against this happening. - This change allows the library's size to be smaller.
- If you use Java, passing null as a not-null annotated argument to a function will no longer throw a
Sizeis now composed of twoDimensionvalues for its width and height.Dimensioncan either be a positive pixel value orDimension.Undefined. See here for more info.BitmapPoolandPoolableViewTargethave been removed from the library.VideoFrameFileFetcherandVideoFrameUriFetcherhave been removed from the library. UseVideoFrameDecoderinstead, which supports all data sources.BlurTransformationandGrayscaleTransformationare removed from the library. If you use them, you can copy their code into your project.- Change
Transition.transitionto 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-progressBitmapFactoryoperations. This value is 4 by default, which improves UI performance. - Add support for
interceptorDispatcher,fetcherDispatcher,decoderDispatcher, andtransformationDispatcher. - Add
GenericViewTarget, which handles commonViewTargetlogic. - Add
ByteBufferto the default supported data types. Disposablehas been refactored and exposes the underlyingImageRequest's job.- Rework the
MemoryCacheAPI. ImageRequest.erroris now set on theTargetifImageRequest.fallbackis null.Transformation.keyis replaced withTransformation.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
ScaleResolverinterface. - Convert
Sizeconstructors to functions. - Change
Dimension.Pixels'stoStringto 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 ofSize.ORIGINAL. - Fix
DiskCache.Builderbeing marked as experimental. OnlyDiskCache's methods are experimental. - Fix case where loading an image into an
ImageViewwith one dimension asWRAP_CONTENTwould load the image at its original size instead of fitting it into the bounded dimension. - Remove component functions from
MemoryCache.Key,MemoryCache.Value, andParameters.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.
rememberImagePainterhas been renamed torememberAsyncImagePainter.- Add support for
AsyncImageandSubcomposeAsyncImage. 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.diskCacheandDiskCache.Builderto configure the disk cache. - You should not use OkHttp's
Cachewith Coil 2.0 as the cache can be corrupted if a thread is interrupted while writing to it. Cache-Controland other cache headers are still supported - exceptVaryheaders, 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.
- Use
ImageRequest's defaultScaleis nowScale.FIT.- This was changed to make
ImageRequest.scaleconsistent with other classes that have a defaultScale. - Requests with an
ImageViewTargetstill have theirScaleauto-detected.
- This was changed to make
ImageRequest's default size is nowSize.ORIGINAL.- Rework the image pipeline classes:
Mapper,Fetcher, andDecoderhave been refactored to be more flexible.Fetcher.keyhas been replaced with a newKeyerinterface.Keyercreates the cache key from the input data.- Add
ImageSource, which allowsDecoders to readFiles 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
NullPointerExceptionimmediately. Kotlin's compile-time null safety guards against this happening. - This change allows the library's size to be smaller.
- If you use Java, passing null as a not-null annotated parameter to a function will no longer throw a
Sizeis now composed of twoDimensionvalues for its width and height.Dimensioncan either be a positive pixel value orDimension.Original.BitmapPoolandPoolableViewTargethave been removed from the library.VideoFrameFileFetcherandVideoFrameUriFetcherare removed from the library. UseVideoFrameDecoderinstead, which supports all data sources.BlurTransformationandGrayscaleTransformationare removed from the library. If you use them, you can copy their code into your project.- Change
Transition.transitionto 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-progressBitmapFactoryoperations. This value is 4 by default, which improves UI performance. - Add support for
interceptorDispatcher,fetcherDispatcher,decoderDispatcher, andtransformationDispatcher. - Add
GenericViewTarget, which handles commonViewTargetlogic. - Add
ByteBufferto the default supported data types. Disposablehas been refactored and exposes the underlyingImageRequest's job.- Rework the
MemoryCacheAPI. ImageRequest.erroris now set on theTargetifImageRequest.fallbackis null.Transformation.keyis replaced withTransformation.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=allcompiler flag. - Fix failing to load image if multiple requests with must-revalidate/e-tag are executed concurrently.
- Fix
DecodeUtils.isSvgreturning false if there is a new line character after the<svgtag. - Make
LocalImageLoader.providesdeprecation message clearer. - Update Compose to 1.1.1.
- Update
accompanist-drawablepainterto 0.23.1.
[2.0.0-alpha09] - February 16, 2022¶
- Fix
AsyncImagecreating invalid constraints. (#1134) - Add
ContentScaleargument toAsyncImagePainter. (#1144)- This should be set to the same value that's set on
Imageto ensure that the image is loaded at the correct size.
- This should be set to the same value that's set on
- Add
ScaleResolverto support lazily resolving theScalefor anImageRequest. (#1134)ImageRequest.scaleshould be replaced byImageRequest.scaleResolver.scale().
- Update Compose to 1.1.0.
- Update
accompanist-drawablepainterto 0.23.0. - Update
androidx.lifecycleto 2.4.1.
[2.0.0-alpha08] - February 7, 2022¶
- Update
DiskCacheandImageSourceto use to Okio'sFileSystemAPI. (#1115)
[2.0.0-alpha07] - January 30, 2022¶
- Significantly improve
AsyncImageperformance and splitAsyncImageintoAsyncImageandSubcomposeAsyncImage. (#1048)SubcomposeAsyncImageprovidesloading/success/error/contentslot APIs and uses subcomposition which has worse performance.AsyncImageprovidesplaceholder/error/fallbackarguments to overwrite thePainterthat's drawn when loading or if the request is unsuccessful.AsyncImagedoes not use subcomposition and has much better performance thanSubcomposeAsyncImage.- Remove
AsyncImagePainter.Stateargument fromSubcomposeAsyncImage.content. Usepainter.stateif needed. - Add
onLoading/onSuccess/onErrorcallbacks to bothAsyncImageandSubcomposeAsyncImage.
- Deprecate
LocalImageLoader. (#1101) - Add support for
ImageRequest.tags. (#1066) - Move
isGif,isWebP,isAnimatedWebP,isHeif, andisAnimatedHeifinDecodeUtilsinto coil-gif. AddisSvgto coil-svg. (#1117) - Convert
FetchResultandDecodeResultto be non-data classes. (#1114) - Remove unused
DiskCache.Buildercontext argument. (#1099) - Fix scaling for bitmap resources with original size. (#1072)
- Fix failing to close
ImageDecoderinImageDecoderDecoder. (#1109) - Fix incorrect scaling when converting a drawable to a bitmap. (#1084)
- Update Compose to 1.1.0-rc03.
- Update
accompanist-drawablepainterto 0.22.1-rc. - Update
androidx.appcompat:appcompat-resourcesto 1.4.1.
[2.0.0-alpha06] - December 24, 2021¶
- Add
ImageSource.Metadatato support decoding from assets, resources, and content URIs without buffering or temporary files. (#1060) - Delay executing the image request until
AsyncImagehas positive constraints. (#1028) - Fix using
DefaultContentforAsyncImageifloading,success, anderrorare all set. (#1026) - Use androidx
LruCacheinstead of the platformLruCache. (#1047) - Update Kotlin to 1.6.10.
- Update Coroutines to 1.6.0.
- Update Compose to 1.1.0-rc01.
- Update
accompanist-drawablepainterto 0.22.0-rc. - Update
androidx.collectionto 1.2.0.
[2.0.0-alpha05] - November 28, 2021¶
- Important: Refactor
Sizeto support using the image's original size for either dimension.Sizeis now composed of twoDimensionvalues for its width and height.Dimensioncan either be a positive pixel value orDimension.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.memoryCacheKeyshould always benullifimageLoader.memoryCacheis null. - Convert
ImageLoader,SizeResolver, andViewSizeResolverconstructor-likeinvokefunctions to top level functions. - Make
CrossfadeDrawablestart and end drawables public API. - Mutate
ImageLoaderplaceholder/error/fallback drawables. - Add default arguments to
SuccessResult's constructor. - Depend on
androidx.collectioninstead ofandroidx.collection-ktx. - Update OkHttp to 4.9.3.
[2.0.0-alpha04] - November 22, 2021¶
- New: Add
AsyncImagetocoil-compose.AsyncImageis a composable that executes anImageRequestasynchronously and renders the result.AsyncImageis intended to replacerememberImagePainterfor most use cases.- Its API is not final and may change before the final 2.0 release.
- It has a similar API to
Imageand supports the same arguments:Alignment,ContentScale,alpha,ColorFilter, andFilterQuality. - It supports overwriting what's drawn for each
AsyncImagePainterstate using thecontent,loading,success, anderrorarguments. - It fixes a number of design issues that
rememberImagePainterhas 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
ImagePaintertoAsyncImagePainterandrememberImagePaintertorememberAsyncImagePainter.ExecuteCallbackis no longer supported. To have theAsyncImagePainterskip waiting foronDrawto be called, setImageRequest.size(OriginalSize)(or any size) instead.- Add an optional
FilterQualityargument torememberAsyncImagePainter.
- Use coroutines for cleanup operations in
DiskCacheand addDiskCache.Builder.cleanupDispatcher. - Fix Compose preview for placeholder set using
ImageLoader.Builder.placeholder. - Mark
LocalImageLoader.currentwith@ReadOnlyComposableto generate more efficient code. - Update Compose to 1.1.0-beta03 and depend on
compose.foundationinstead ofcompose.ui. - Update
androidx.appcompat-resourcesto 1.4.0.
[2.0.0-alpha03] - November 12, 2021¶
- Add ability to load music thumbnails on Android 29+. (#967)
- Fix: Use
context.resourcesto load resources for current package. (#968) - Fix:
clear->disposereplacement expression. (#970) - Update Compose to 1.0.5.
- Update
accompanist-drawablepainterto 0.20.2. - Update Okio to 3.0.0.
- Update
androidx.annotationto 1.3.0. - Update
androidx.coreto 1.7.0. - Update
androidx.lifecycleto 2.4.0.- Remove dependency on
lifecycle-common-java8as it's been merged intolifecycle-common.
- Remove dependency on
[2.0.0-alpha02] - October 24, 2021¶
- Add a new
coil-bomartifact which includes a bill of materials.- Importing
coil-bomallows you to depend on other Coil artifacts without specifying a version.
- Importing
- 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=allor-Xjvm-default=all-compatibilityto 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 byFiles. This avoids unnecessary copying when an Android API requires aFileto decode (e.g.MediaMetadataRetriever). - Support reading from/writing to the disk cache files directly.
- Use
ImageLoader.Builder.diskCacheandDiskCache.Builderto configure the disk cache. - You should not use OkHttp's
Cachewith Coil 2.0 as it can be corrupted if it's interrupted while writing to it. Cache-Controland other cache headers are still supported - exceptVaryheaders, 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.
- This change was made to:
- Important:
ImageRequest's defaultScaleis nowScale.FIT- This was changed to make
ImageRequest.scaleconsistent with other classes that have a defaultScale. - Requests with an
ImageViewTargetstill have their scale autodetected.
- This was changed to make
- Significant changes to the image pipeline classes:
Mapper,Fetcher, andDecoderhave been refactored to be more flexible.Fetcher.keyhas been replaced with a newKeyerinterface.Keyercreates the cache key from the input data.- Adds
ImageSource, which allowsDecoders to decodeFiles directly.
BitmapPoolandPoolableViewTargethave 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
Drawablein more places (e.g.Listener,Disposable). Additionally, this means Coil doesn't have to clearImageViews, 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.
MemoryCachehas 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
NullPointerExceptionimmediately. If you use Kotlin, there is essentially no change. - This change allows the library's size to be smaller.
- If you use Java, passing null as a not-null annotated parameter to a function will no longer throw a
VideoFrameFileFetcherandVideoFrameUriFetcherare removed from the library. UseVideoFrameDecoderinstead, which supports all data sources.- Adds support for
bitmapFactoryMaxParallelism, which restricts the maximum number of in-progressBitmapFactoryoperations. This value is 4 by default, which improves UI performance. - Adds support for
interceptorDispatcher,fetcherDispatcher,decoderDispatcher, andtransformationDispatcher. Disposablehas been refactored and exposes the underlyingImageRequest's job.- Change
Transition.transitionto be a non-suspending function as it's no longer needed to suspend the transition until it completes. - Add
GenericViewTarget, which handles commonViewTargetlogic. BlurTransformationandGrayscaleTransformationare removed from the library.- If you use them, you can copy their code into your project.
ImageRequest.erroris now set on theTargetifImageRequest.fallbackis null.Transformation.keyis replaced withTransformation.cacheKey.ImageRequest.ListenerreturnsSuccessResult/ErrorResultinonSuccessandonErrorrespectively.- Add
ByteBuffers to the default supported data types. - Remove
toStringimplementations 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
ImageResulttoImagePainter.State.SuccessandImagePainter.State.Error. (#887)- This is a binary incompatible change to the signatures of
ImagePainter.State.SuccessandImagePainter.State.Error, however these APIs are marked as experimental.
- This is a binary incompatible change to the signatures of
- Only execute
CrossfadeTransitionifView.isShownistrue. Previously it would only checkView.isVisible. (#898) - Fix potential memory cache miss if scaling multiplier is slightly less than 1 due to a rounding issue. (#899)
- Make non-inlined
ComponentRegistrymethods public. (#925) - Depend on
accompanist-drawablepainterand remove Coil's customDrawablePainterimplementation. (#845) - Remove use of a Java 8 method to guard against desugaring issue. (#924)
- Promote
ImagePainter.ExecuteCallbackto 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-composenow depends oncompose.uiinstead ofcompose.foundation.compose.uiis a smaller dependency as it's a subset ofcompose.foundation.
- Update Jetpack Compose to 1.0.1.
- Update Kotlin to 1.5.21.
- Update Coroutines to 1.5.1.
- Update
androidx.exifinterface:exifinterfaceto 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-resourcesto 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
allowConversionToBitmapto enable/disable the automatic bitmap conversion forTransformations. (#775) - Add
enforceMinimumFrameDelaytoImageDecoderDecoderandGifDecoderto 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-ktxto 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.fallbacksetting theerrordrawable instead of thefallbackdrawable. - 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-resourcesto 1.3.0. - Update
androidx.core:core-ktxto 1.5.0.
[1.2.1] - April 27, 2021¶
- Fix
VideoFrameUriFetcherattempting 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,
SvgDecoderused an SVG'swidth/heightelements to determine its aspect ratio, however this doesn't correctly follow the SVG specification. - To revert to the old behaviour set
useViewBoundsAsIntrinsicSize = falsewhen constructing yourSvgDecoder.
- Previously,
- New: Add
VideoFrameDecoderto 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
ImageLoaderinstances.
- Importantly, this enables sharing memory caches between
- 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
EmptyBitmapPoolimplementation if bitmap pooling is disabled. (#638)- Without this fix bitmap pooling was still disabled properly, however it used a more heavyweight
BitmapPoolimplementation.
- Without this fix bitmap pooling was still disabled properly, however it used a more heavyweight
- Fix case where
MovieDrawable.getOpacitywould 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-java8to 2.3.1.
[1.1.1] - January 11, 2021¶
- Fix a case where
ViewSizeResolver.sizecould throw anIllegalStateExceptiondue to resuming a coroutine more than once. - Fix
HttpFetcherblocking 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 aNetworkOnMainThreadExceptionunlessImageRequest.networkCachePolicyis set toCachePolicy.DISABLEDorCachePolicy.WRITE_ONLY.
- Requests that are forced to execute on the main thread using
- Rotate video frames from
VideoFrameFetcherif 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
CENTERandMATRIXImageViewscale types to resolve toOriginalSize. (#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 aViewSizeResolverwhen constructing your request.
- Important: Return the display size from
ViewSizeResolverif the view's layout param isWRAP_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.Factorya functional interface. (#575) - Stabilize
EventListener. (#574) - Add
Stringoverload forImageRequest.Builder.placeholderMemoryCacheKey. - Add
@JvmOverloadsto theViewSizeResolverconstructor. - 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-parcelizeplugin. - 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=allcompiler flag due to instability.- This is a source compatible, but binary incompatible change from previous release candidate versions.
- Add
Context.imageLoaderextension function. (#534) - Add
ImageLoader.executeBlockingextension 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
stdlibinstead ofstdlib-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.0and below where the memory cache would be checked synchronously on the main thread. - To revert to using the same behaviour as
0.12.0where the memory cache is checked onImageRequest.dispatcher, setImageLoader.Builder.launchInterceptorChainOnMainThread(false). - See
launchInterceptorChainOnMainThreadfor more information.
- This largely restores the behaviour from
- Fix: Fix potential memory leak if request is started on a
ViewTargetin a detached fragment. (#518) - Fix: Use
ImageRequest.contextto load resource URIs. (#517) - Fix: Fix race condition that could cause subsequent requests to not be saved to the disk cache. (#510)
- Fix: Use
blockCountLongandblockSizeLongon API 18.
- Make
ImageLoaderFactorya fun interface. - Add
ImageLoader.Builder.addLastModifiedToFileCacheKeywhich allows you to enable/disable adding the last modified timestamp to the memory cache key for an image loaded from aFile.
- 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=allin your build file. - This generates Java 8 default methods for default Kotlin interface methods.
- See here for how to enable
- Remove all existing deprecated methods in 0.12.0.
- Update Coroutines to 1.3.9.
[0.12.0] - August 18, 2020¶
- Breaking:
LoadRequestandGetRequesthave been replaced withImageRequest:ImageLoader.execute(LoadRequest)->ImageLoader.enqueue(ImageRequest)ImageLoader.execute(GetRequest)->ImageLoader.execute(ImageRequest)ImageRequestimplementsequals/hashCode.
- Breaking: A number of classes were renamed and/or changed package:
coil.request.RequestResult->coil.request.ImageResultcoil.request.RequestDisposable->coil.request.Disposablecoil.bitmappool.BitmapPool->coil.bitmap.BitmapPoolcoil.DefaultRequestOptions->coil.request.DefaultRequestOptions
- Breaking:
SparseIntArraySethas been removed from the public API. - Breaking:
TransitionTargetno longer implementsViewTarget. - Breaking:
ImageRequest.Listener.onSuccess's signature has changed to return anImageResult.Metadatainstead of just aDataSource. - 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.
- This change was also necessary to support executing
- Important:
Mappersare now executed on a background dispatcher. As a side effect, automatic bitmap sampling is no longer automatically supported. To achieve the same effect, use theMemoryCache.Keyof a previous request as theplaceholderMemoryCacheKeyof the subsequent request. See here for an example.- The
placeholderMemoryCacheKeyAPI offers more freedom as you can "link" two image requests with different data (e.g. different URLs for small/large images).
- The
- Important: Coil's
ImageViewextension functions have been moved from thecoil.apipackage to thecoilpackage.- Use find + replace to refactor
import coil.api.load->import coil.load. Unfortunately, it's not possible to use Kotlin'sReplaceWithfunctionality to replace imports.
- Use find + replace to refactor
- Important: Use standard crossfade if drawables are not the same image.
- Important: Prefer immutable bitmaps on API 24+.
- Important:
MeasuredMapperhas been deprecated in favour of the newInterceptorinterface. See here for an example of how to convert aMeasuredMapperinto anInterceptor.Interceptoris a much less restrictive API that allows for a wider range of custom logic.
- Important:
ImageRequest.datais now not null. If you create anImageRequestwithout setting its data it will returnNullRequestDataas its data.
- New: Add support for direct read/write access to an
ImageLoader'sMemoryCache. See the docs for more information. - New: Add support for
Interceptors. See the docs for more information. Coil'sInterceptordesign 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).
- Bitmap pooling is most effective on API 23 and below, but may still be benificial on API 24 and up (by eagerly calling
- 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.0androidx.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
ContentProviderso it doesn't run any code at app startup.
- This enables removing Coil's
- Breaking: Convert
SparseIntArraySet.sizeto a val. (#380) - Breaking: Move
Parameters.count()to an extension function. (#403) - Breaking: Make
BitmapPool.maxSizean Int. (#404)
- Important: Make
ImageLoader.shutdown()optional (similar toOkHttpClient). (#385)
- Reduce the default memory cache size to 20%. (#390)
- To restore the existing behaviour set
ImageLoaderBuilder.availableMemoryPercentage(0.25)when creating yourImageLoader.
- To restore the existing behaviour set
- 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://example.com/image.jpg") { target(imageView) } val drawable = imageLoader.get("https://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://example.com/image.jpg") .target(imageView) .build() val disposable = imageLoader.execute(request) val request = GetRequest.Builder(context) .data("https://example.com/image.jpg") .size(512, 512) .build() val drawable = imageLoader.execute(request).drawable- If you're using the
io.coil-kt:coilartifact, you can callCoil.execute(request)to execute the request with the singletonImageLoader.
- If you're using the
-
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.
- This means an image will always be returned from an
-
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
Applicationto simplify singleton initialization.
Full Release Notes¶
- Important: Deprecate DSL syntax in favour of builder syntax. (#267)
- Important: Deprecate
CoilandImageLoaderextension functions. (#322) - Breaking: Return sealed
RequestResulttype fromImageLoader.execute(GetRequest). (#349) - Breaking: Rename
ExperimentalCoiltoExperimentalCoilApi. Migrate from@Experimentalto@RequiresOptIn. (#306) - Breaking: Replace
CoilLoggerwithLoggerinterface. (#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 fullRequestobject instead of just its data. - Breaking:
GetRequestBuildernow requires aContextin its constructor. - Breaking: Several properties on
Requestare 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 afterTarget.onStart(). (#348)
- New: Add
WeakMemoryCacheimplementation. (#295) - New: Add
coil-videoto 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
errorandfallbackdrawables 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
ImageDecoderDecodercrash 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
ImageViewhas a matchingSizeResolver. (#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
ImageLoadermethods with@MainThread. - Avoid creating a
LifecycleCoroutineDispatcherif 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_8888bitmap, it would be possible to have aRGBA_F16bitmap returned to you from the memory cache. Now, the cached config and the requested config must be equal. - Make
scaleanddurationMillispublic inCrossfadeDrawableandCrossfadeTransition.
[0.9.3] - February 1, 2020¶
- Fix: Translate child drawable inside
ScaleDrawableto 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.trimMemorypublic. - 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.transformnow includes aSizeparameter. This is to support transformations that change the size of the outputBitmapbased on the size of theTarget. Requests with transformations are now also exempt from image sampling. - Breaking:
Transformations are now applied to any type ofDrawable. Before,Transformations would be skipped if the inputDrawablewas not aBitmapDrawable. Now,Drawables are rendered to aBitmapbefore applying theTransformations. - Breaking: Passing
nulldata toImageLoader.loadis now treated as an error and callsTarget.onErrorandRequest.Listener.onErrorwith aNullRequestDataException. This change was made to support setting afallbackdrawable if data isnull. Previously the request was silently ignored. - Breaking:
RequestDisposable.isDisposedis now aval.
- New: Support for custom transitions. See here for more info. Transitions are marked as experimental as the API is incubating.
- New: Add
RequestDisposable.awaitto support suspending while aLoadRequestis in progress. - New: Support setting a
fallbackdrawable when request data is null. - New: Add
Precision. This makes the size of the outputDrawableexact while enabling scaling optimizations for targets that support scaling (e.g.ImageViewTarget). See its documentation for more information. - New: Add
RequestBuilder.aliasKeysto support matching multiple cache keys.
- Fix: Make RequestDisposable thread safe.
- Fix:
RoundedCornersTransformationnow crops to the size of the target then rounds the corners. - Fix:
CircleCropTransformationnow 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
MovieDrawablenot 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:
SvgDrawablehas been removed. Instead, SVGs are now prerendered toBitmapDrawables bySvgDecoder. This makes SVGs significantly less expensive to render on the main thread. AlsoSvgDecodernow requires aContextin its constructor. - Breaking:
SparseIntArraySetextension functions have moved to thecoil.extensionpackage.
- New: Support setting per-request network headers. See here for more info.
- New: Add new
ParametersAPI 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
subtractPaddingattribute 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<*>.repeatCountto 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-resourcesfromcompileOnlytoimplementationforcoil-base.
[0.7.0] - September 8, 2019¶
- Breaking:
ImageLoaderBuilder.okHttpClient(OkHttpClient.Builder.() -> Unit)is nowImageLoaderBuilder.okHttpClient(() -> OkHttpClient). The initializer is also now called lazily on a background thread. If you set a customOkHttpClientyou must setOkHttpClient.cacheto enable disk caching. If you don't set a customOkHttpClient, Coil will create the defaultOkHttpClientwhich has disk caching enabled. The default Coil cache can be created usingCoilUtils.createDefaultCache(context). e.g.:
val imageLoader = ImageLoader(context) {
okHttpClient {
OkHttpClient.Builder()
.cache(CoilUtils.createDefaultCache(context))
.build()
}
}
- Breaking:
Fetcher.keyno longer has a default implementation. - Breaking: Previously, only the first applicable
Mapperwould be called. Now, all applicableMappers will be called. No API changes. - Breaking: Minor named parameter renaming:
url->uri,factory->initializer.
- New:
coil-svgartifact, which has anSvgDecoderthat supports automatically decoding SVGs. Powered by AndroidSVG. Thanks @rharter. - New:
load(String)andget(String)now accept any of the supported Uri schemes. e.g. You can now doimageView.load("file:///path/to/file.jpg"). - New: Refactor ImageLoader to use
Call.Factoryinstead ofOkHttpClient. This allows lazy initialization of the networking resources usingImageLoaderBuilder.okHttpClient { OkHttpClient() }. Thanks @ZacSweers. - New:
RequestBuilder.decoderto explicitly set the decoder for a request. - New:
ImageLoaderBuilder.allowHardwareto 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.0androidx.core:core-ktx-> 1.1.0androidx.lifecycle:lifecycle-common-java8-> 2.1.0
- Replace
appcompatwithappcompat-resourcesas an optionalcompileOnlydependency.appcompat-resourcesis 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.