- Fix setting
ImageRequest.scale
based on anImageView
'sScaleType
. - Fix edge case where
DiskCache
would not track removal of an entry after deleting its files. - Pass throwable to
Logger
when logging errors. - Don't replace
kotlin-stdlib-jdk7
andkotlin-stdlib-jdk8
withkotlin-stdlib
.
- Fix crash when invoking
OkHttpNetworkFetcherFactory
with a customCacheStrategy
on Android. - Fix
CacheControlCacheStrategy
computing the age of a cache entry incorrectly. - Fix case where
ImageRequest.bitmapConfig
would only be respected on >= API 28 if it wasARGB_8888
orHARDWARE
.
- Fix crash when calling
Image.toBitmap
with a hardware bitmap-backedBitmapImage
. - Fix
AsyncImageModelEqualityDelegate.Default
comparing equality incorrectly for non-ImageRequest
models.
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.
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
remember
functions forConstraintsSizeResolver
andDrawScopeSizeResolver
. - Remove
EqualityDelegate
as a parameter toAsyncImage
. Instead, it should be set throughLocalAsyncImageModelEqualityDelegate
. - Fix
AsyncImage
not rendering when parent composable usesIntrinsicSize
. - Fix
AsyncImage
filling the available constraints whenAsyncImagePainter
has no child painter. - Fix
rememberAsyncImagePainter
recomposing infinitely when its state is observed due toEqualityDelegate
being ignored. - Fix parsing
File
/Path
paths with special characters. - Fix using custom
FileSystem
implementations withVideoFrameDecoder
. - Update Ktor to
3.0.0
. - Update
androidx.annotation
to1.9.0
.
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
addLastModifiedToFileCacheKey
by 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-control
artifact, which implementsCache-Control
header support. - New: Add
scaleToDensity
property toSvgDecoder.Factory
. This property ensure SVGs with intrinsic dimensions are multiplied by the devices density (only supported on Android). - Rename
ExifOrientationPolicy
toExifOrientationStrategy
. - Remove unshareable images from the
MemoryCache
on get. - Make
ConstraintsSizeResolver
public. - Stabilize
setSingletonImageLoaderFactory
. - Restore optimized JVM I/O functions in
coil-network-ktor3
- Add
pdf
to list of mime types. - Update compile sdk to 35.
- Update Kotlin to 2.0.20.
- Update Okio to 3.9.1.
- BREAKING: Replace
ImageLoader.Builder.networkObserverEnabled
with aConnectivityChecker
interface forNetworkFetcher
.- To disable the network observer, pass
ConnectivityChecker.ONLINE
to 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
:
AsyncImage(
model = Res.getUri("drawable/image.jpg"),
contentDescription = null,
)
- Add
maxBitmapSize
property toImageLoader
andImageRequest
.- 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.ORIGINAL
and 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
ExifOrientationPolicy
to be an interface to support custom policies. - Fix
Uri
handling of Windows file paths. - Remove
@ExperimentalCoilApi
from theImage
APIs. - Update Kotlin to 2.0.10.
- BREAKING: Rename the
io.coil-kt.coil3:coil-network-ktor
artifact toio.coil-kt.coil3:coil-network-ktor2
which depends on Ktor 2.x. Additionally, introduceio.coil-kt.coil3:coil-network-ktor3
which depends on Ktor 3.x.wasmJs
support is only available in Ktor 3.x. - New: Add
AsyncImagePainter.restart()
to manually restart an image request. - Remove
@ExperimentalCoilApi
fromNetworkClient
and related classes. - Optimize
ImageRequest
to avoid unnecessaryExtras
andMap
allocations.
- 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.
- BREAKING: Rename
ImageRequest
andImageLoader
dispatcher
methods tocoroutineContext
. For instance,ImageRequest.Builder.dispatcher
is nowImageRequest.Builder.coroutineContext
. This was renamed as the method now accepts anyCoroutineContext
and 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 applied
which 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-swing
on JVM. If it's not imported thenImageRequest
s won't be dispatched immediately and will have one frame of delay before setting theImageRequest.placeholder
or resolving from the memory cache.
- NOTE: This reintroduces a soft dependency on
- BREAKING:
AsyncImagePainter
no longer waits foronDraw
by default and instead usesSize.ORIGINAL
.- This fixes compatibility issues with Roborazzi/Paparazzi and overall improves test reliability.
- To revert back to waiting for
onDraw
, setDrawScopeSizeResolver
as yourImageRequest.sizeResolver
.
- BREAKING: Refactor the multiplatform
Image
API. Notably,asCoilImage
has been renamed toasImage
. - BREAKING:
AsyncImagePainter.state
has been changed toStateFlow<AsyncImagePainter.State>
. UsecollectAsState
to observe its value. This improves performance. - BREAKING:
AsyncImagePainter.imageLoader
andAsyncImagePainter.request
have been combined intoStateFlow<AsyncImagePainter.Inputs>
. UsecollectAsState
to observe its value. This improves performance. - BREAKING: Remove support for
android.resource://example.package.name/drawable/image
URIs as it prevents resource shrinking optimizations.- If you still needs its functionality you can manually include
ResourceUriMapper
in your component registry.
- If you still needs its functionality you can manually include
- New: Introduce
AsyncImagePreviewHandler
to support controllingAsyncImagePainter
's preview rendering behavior.- Use
LocalAsyncImagePreviewHandler
to override the preview behavior. - As part of this change and other
coil-compose
improvements,AsyncImagePainter
now attempts to execute execute theImageRequest
by 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
CoroutineContext
to anyCoroutineDispatcher
methods. (#2241). - New: Support the weak reference memory cache on JS and WASM JS.
- Don't dispatch to
Dispatchers.Main.immediate
in Compose. As a side-effect,kotlinx-coroutines-swing
no longer needs to be imported on JVM. - Don't call
async
and create a disposable in Compose to improve performance (thanks @mlykotom!). (#2205) - Fix passing global
ImageLoader
extras toOptions
. (#2223) - Fix
crossfade(false)
not working on non-Android targets. - Fix VP8X feature flags byte offset (#2199).
- Convert
SvgDecoder
on 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
ScaleDrawable
fromcoil-gif
tocoil-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.
- Downgrade Skiko to 0.7.93.
- For the full list of important changes in 3.x, check out the upgrade guide.
- New: Support the
wasmJs
target. - Create
DrawablePainter
andDrawableImage
to support drawingImage
s that aren't backed by aBitmap
on non-Android platforms.- The
Image
APIs are experimental and likely to change between alpha releases.
- The
- Update
ContentPainterModifier
to 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/fallback
not 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.
- Make
rememberAsyncImagePainter
,AsyncImage
, andSubcomposeAsyncImage
restartable and skippable. This improves performance by avoiding recomposition unless one of the composable's arguments changes.- Add an optional
modelEqualityDelegate
argument torememberAsyncImagePainter
,AsyncImage
, andSubcomposeAsyncImage
to control whether themodel
will trigger a recomposition.
- Add an optional
- Update
ContentPainterModifier
to 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
, andSubcomposeAsyncImage
ifImageRequest.listener
orImageRequest.target
change. - 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.collection
to 1.4.0. - Update
androidx.lifecycle
to 2.7.0.
- Breaking: Remove
Lazy
fromOkHttpNetworkFetcherFactory
andKtorNetworkFetcherFactory
's public API. - Expose
Call.Factory
instead ofOkHttpClient
inOkHttpNetworkFetcherFactory
. - Convert
NetworkResponseBody
to wrap aByteString
. - Downgrade Compose to 1.5.12.
- For the full list of important changes, check out the upgrade guide.
- Breaking:
coil-network
has been renamed tocoil-network-ktor
. Additionally, there is a newcoil-network-okhttp
artifact that depends on OkHttp and doesn't require specifying a Ktor engine.- Depending on which artifact you import you can reference the
Fetcher.Factory
manually usingKtorNetworkFetcherFactory
orOkHttpNetworkFetcherFactory
.
- Depending on which artifact you import you can reference the
- Support loading
NSUrl
on Apple platforms. - Add
clipToBounds
parameter toAsyncImage
. - For the full list of important changes, check out the upgrade guide.
- 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.video
respectively. This helps avoid class name conflicts with other artifacts. - Breaking:
ImageDecoderDecoder
has 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-alpha01
you 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
ComponentRegistry
manually. 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-svg
on all platforms. It's backed by AndroidSVG on Android and SVGDOM on non-Android platforms. - Coil now uses Android's
ImageDecoder
API internally, which has performance benefits when decoding directly from a file, resource, or content URI. - Fix: Multiple
coil3.Uri
parsing fixes. - For the full list of important changes, check out the upgrade guide.
- 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.coil3
and 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-base
andcoil-compose-base
artifacts were renamed tocoil-core
andcoil-compose-core
respectively to align with the naming conventions used by Coroutines, Ktor, and AndroidX. - For the full list of important changes, check out the upgrade guide.
- New: Add
MediaDataSourceFetcher.Factory
to support decodingMediaDataSource
implementations incoil-video
. (#1795) - Add the
SHIFT6m
device 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 Modified
when cached headers include non-ASCII characters. (#1839) - Fix:
FakeImageEngine
not 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-drawablepainter
to 0.32.0. - Update
androidx.annotation
to 1.7.0. - Update
androidx.compose.foundation
to 1.5.4. - Update
androidx.core
to 1.12.0. - Update
androidx.exifinterface:exifinterface
to 1.3.6. - Update
androidx.lifecycle
to 2.6.2. - Update
com.squareup.okhttp3
to 4.12.0. - Update
com.squareup.okio
to 3.6.0.
- Rename
DiskCache
get
/edit
toopenSnapshot
/openEditor
. - Don't automatically convert
ColorDrawable
toColorPainter
inAsyncImagePainter
. - Annotate simple
AsyncImage
overloads with@NonRestartableComposable
. - Fix: Call
Context.cacheDir
lazily inImageSource
. - Fix: Fix publishing
coil-bom
. - Fix: Fix always setting bitmap config to
ARGB_8888
if hardware bitmaps are disabled. - Update Kotlin to 1.8.21.
- Update Coroutines to 1.7.1.
- Update
accompanist-drawablepainter
to 0.30.1. - Update
androidx.compose.foundation
to 1.4.3. - Update
androidx.profileinstaller:profileinstaller
to 1.3.1. - Update
com.squareup.okhttp3
to 4.11.0.
- New: Introduce a new
coil-test
artifact, 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:
DiskCache
now properly computes its maximum size if passed a directory that does not exist. #1620 - Make
Coil.reset
public API. #1506 - Enable Java default method generation. #1491
- Update Kotlin to 1.8.10.
- Update
accompanist-drawablepainter
to 0.30.0. - Update
androidx.annotation
to 1.6.0. - Update
androidx.appcompat:appcompat-resources
to 1.6.1. - Update
androidx.compose.foundation
to 1.4.0. - Update
androidx.core
to 1.9.0. - Update
androidx.exifinterface:exifinterface
to 1.3.6. - Update
androidx.lifecycle
to 2.6.1. - Update
okio
to 3.3.0.
- Ensure an image loader is fully initialized before registering its system callbacks. #1465
- Set the preferred bitmap config in
VideoFrameDecoder
on 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.annotation
to 1.5.0.
- Fix:
RoundedCornersTransformation
now properly scales theinput
bitmap. - Remove dependency on the
kotlin-parcelize
plugin. - Update compile SDK to 33.
- Downgrade
androidx.appcompat:appcompat-resources
to 1.4.2 to work around #1423.
- New: Add
ImageRequest.videoFramePercent
tocoil-video
to support specifying the video frame as a percent of the video's duration. - New: Add
ExifOrientationPolicy
to configure howBitmapFactoryDecoder
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.
- New: Support loading
ByteArray
s. (#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)
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
incoil-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
andDiskCache.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 - exceptVary
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.
- Use
- The minimum supported API is now 21.
ImageRequest
's defaultScale
is nowScale.FIT
.- This was changed to make
ImageRequest.scale
consistent with other classes that have a defaultScale
. - Requests with an
ImageViewTarget
still have theirScale
auto-detected.
- This was changed to make
- Rework the image pipeline classes:
Mapper
,Fetcher
, andDecoder
have been refactored to be more flexible.Fetcher.key
has been replaced with a newKeyer
interface.Keyer
creates the cache key from the input data.- Add
ImageSource
, which allowsDecoder
s to readFile
s directly using Okio's file system API.
- Rework the Jetpack Compose integration:
rememberImagePainter
andImagePainter
have been renamed torememberAsyncImagePainter
andAsyncImagePainter
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.
- If you use Java, passing null as a not-null annotated argument to a function will no longer throw a
Size
is now composed of twoDimension
values for its width and height.Dimension
can either be a positive pixel value orDimension.Undefined
. See here for more info.BitmapPool
andPoolableViewTarget
have been removed from the library.VideoFrameFileFetcher
andVideoFrameUriFetcher
have been removed from the library. UseVideoFrameDecoder
instead, which supports all data sources.BlurTransformation
andGrayscaleTransformation
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-progressBitmapFactory
operations. This value is 4 by default, which improves UI performance. - Add support for
interceptorDispatcher
,fetcherDispatcher
,decoderDispatcher
, andtransformationDispatcher
. - Add
GenericViewTarget
, which handles commonViewTarget
logic. - Add
ByteBuffer
to the default supported data types. Disposable
has been refactored and exposes the underlyingImageRequest
's job.- Rework the
MemoryCache
API. ImageRequest.error
is now set on theTarget
ifImageRequest.fallback
is null.Transformation.key
is 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 beDimension.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.
- Remove the
ScaleResolver
interface. - Convert
Size
constructors to functions. - Change
Dimension.Pixels
'stoString
to only be its pixel value. - Guard against a rare crash in
SystemCallbacks.onTrimMemory
. - Update Coroutines to 1.6.1.
- Revert
ImageRequest
's default size to be the size of the current display instead ofSize.ORIGINAL
. - Fix
DiskCache.Builder
being marked as experimental. OnlyDiskCache
's methods are experimental. - Fix case where loading an image into an
ImageView
with one dimension asWRAP_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
, andParameters.Entry
.
Significant changes since 1.4.0
:
- The minimum supported API is now 21.
- Rework the Jetpack Compose integration.
rememberImagePainter
has been renamed torememberAsyncImagePainter
.- Add support for
AsyncImage
andSubcomposeAsyncImage
. 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
andDiskCache.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 - exceptVary
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.
- Use
ImageRequest
's defaultScale
is nowScale.FIT
.- This was changed to make
ImageRequest.scale
consistent with other classes that have a defaultScale
. - Requests with an
ImageViewTarget
still have theirScale
auto-detected.
- This was changed to make
ImageRequest
's default size is nowSize.ORIGINAL
.- Rework the image pipeline classes:
Mapper
,Fetcher
, andDecoder
have been refactored to be more flexible.Fetcher.key
has been replaced with a newKeyer
interface.Keyer
creates the cache key from the input data.- Add
ImageSource
, which allowsDecoder
s to readFile
s 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.
- If you use Java, passing null as a not-null annotated parameter to a function will no longer throw a
Size
is now composed of twoDimension
values for its width and height.Dimension
can either be a positive pixel value orDimension.Original
.BitmapPool
andPoolableViewTarget
have been removed from the library.VideoFrameFileFetcher
andVideoFrameUriFetcher
are removed from the library. UseVideoFrameDecoder
instead, which supports all data sources.BlurTransformation
andGrayscaleTransformation
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-progressBitmapFactory
operations. This value is 4 by default, which improves UI performance. - Add support for
interceptorDispatcher
,fetcherDispatcher
,decoderDispatcher
, andtransformationDispatcher
. - Add
GenericViewTarget
, which handles commonViewTarget
logic. - Add
ByteBuffer
to the default supported data types. Disposable
has been refactored and exposes the underlyingImageRequest
's job.- Rework the
MemoryCache
API. ImageRequest.error
is now set on theTarget
ifImageRequest.fallback
is null.Transformation.key
is 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=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.
- Fix
AsyncImage
creating invalid constraints. (#1134) - Add
ContentScale
argument toAsyncImagePainter
. (#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.
- This should be set to the same value that's set on
- Add
ScaleResolver
to support lazily resolving theScale
for anImageRequest
. (#1134)ImageRequest.scale
should be replaced byImageRequest.scaleResolver.scale()
.
- Update Compose to 1.1.0.
- Update
accompanist-drawablepainter
to 0.23.0. - Update
androidx.lifecycle
to 2.4.1.
- Update
DiskCache
andImageSource
to use to Okio'sFileSystem
API. (#1115)
- Significantly improve
AsyncImage
performance and splitAsyncImage
intoAsyncImage
andSubcomposeAsyncImage
. (#1048)SubcomposeAsyncImage
providesloading
/success
/error
/content
slot APIs and uses subcomposition which has worse performance.AsyncImage
providesplaceholder
/error
/fallback
arguments to overwrite thePainter
that's drawn when loading or if the request is unsuccessful.AsyncImage
does not use subcomposition and has much better performance thanSubcomposeAsyncImage
.- Remove
AsyncImagePainter.State
argument fromSubcomposeAsyncImage.content
. Usepainter.state
if needed. - Add
onLoading
/onSuccess
/onError
callbacks to bothAsyncImage
andSubcomposeAsyncImage
.
- Deprecate
LocalImageLoader
. (#1101) - Add support for
ImageRequest.tags
. (#1066) - Move
isGif
,isWebP
,isAnimatedWebP
,isHeif
, andisAnimatedHeif
inDecodeUtils
into coil-gif. AddisSvg
to coil-svg. (#1117) - Convert
FetchResult
andDecodeResult
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
inImageDecoderDecoder
. (#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.
- 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
forAsyncImage
ifloading
,success
, anderror
are all set. (#1026) - Use androidx
LruCache
instead 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-drawablepainter
to 0.22.0-rc. - Update
androidx.collection
to 1.2.0.
- Important: Refactor
Size
to support using the image's original size for either dimension.Size
is now composed of twoDimension
values for its width and height.Dimension
can 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.memoryCacheKey
should always benull
ifimageLoader.memoryCache
is null. - Convert
ImageLoader
,SizeResolver
, andViewSizeResolver
constructor-likeinvoke
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 ofandroidx.collection-ktx
. - Update OkHttp to 4.9.3.
- New: Add
AsyncImage
tocoil-compose
.AsyncImage
is a composable that executes anImageRequest
asynchronously and renders the result.AsyncImage
is intended to replacerememberImagePainter
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
, andFilterQuality
. - It supports overwriting what's drawn for each
AsyncImagePainter
state using thecontent
,loading
,success
, anderror
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
toAsyncImagePainter
andrememberImagePainter
torememberAsyncImagePainter
.ExecuteCallback
is no longer supported. To have theAsyncImagePainter
skip waiting foronDraw
to be called, setImageRequest.size(OriginalSize)
(or any size) instead.- Add an optional
FilterQuality
argument torememberAsyncImagePainter
.
- Use coroutines for cleanup operations in
DiskCache
and addDiskCache.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 ofcompose.ui
. - Update
androidx.appcompat-resources
to 1.4.0.
- 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 intolifecycle-common
.
- Remove dependency on
- 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.
- 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.
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
ImageSource
s backed byFile
s. This avoids unnecessary copying when an Android API requires aFile
to decode (e.g.MediaMetadataRetriever
). - Support reading from/writing to the disk cache files directly.
- Use
ImageLoader.Builder.diskCache
andDiskCache.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 - exceptVary
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.
- This change was made to:
- Important:
ImageRequest
's defaultScale
is nowScale.FIT
- This was changed to make
ImageRequest.scale
consistent with other classes that have a defaultScale
. - Requests with an
ImageViewTarget
still have their scale autodetected.
- This was changed to make
- Significant changes to the image pipeline classes:
Mapper
,Fetcher
, andDecoder
have been refactored to be more flexible.Fetcher.key
has been replaced with a newKeyer
interface.Keyer
creates the cache key from the input data.- Adds
ImageSource
, which allowsDecoder
s to decodeFile
s directly.
BitmapPool
andPoolableViewTarget
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 clearImageView
s, 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.
- If you use Java, passing null as a not-null annotated parameter to a function will no longer throw a
VideoFrameFileFetcher
andVideoFrameUriFetcher
are removed from the library. UseVideoFrameDecoder
instead, which supports all data sources.- Adds support for
bitmapFactoryMaxParallelism
, which restricts the maximum number of in-progressBitmapFactory
operations. This value is 4 by default, which improves UI performance. - Adds support for
interceptorDispatcher
,fetcherDispatcher
,decoderDispatcher
, andtransformationDispatcher
. Disposable
has been refactored and exposes the underlyingImageRequest
'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 commonViewTarget
logic. BlurTransformation
andGrayscaleTransformation
are removed from the library.- If you use them, you can copy their code into your project.
ImageRequest.error
is now set on theTarget
ifImageRequest.fallback
is null.Transformation.key
is replaced withTransformation.cacheKey
.ImageRequest.Listener
returnsSuccessResult
/ErrorResult
inonSuccess
andonError
respectively.- Add
ByteBuffer
s 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.
- New: Add
ImageResult
toImagePainter.State.Success
andImagePainter.State.Error
. (#887)- This is a binary incompatible change to the signatures of
ImagePainter.State.Success
andImagePainter.State.Error
, however these APIs are marked as experimental.
- This is a binary incompatible change to the signatures of
- Only execute
CrossfadeTransition
ifView.isShown
istrue
. 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
ComponentRegistry
methods public. (#925) - Depend on
accompanist-drawablepainter
and remove Coil's customDrawablePainter
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.
coil-compose
now depends oncompose.ui
instead ofcompose.foundation
.compose.ui
is 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:exifinterface
to 1.3.3.
- 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.
- 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 forTransformation
s. (#775) - Add
enforceMinimumFrameDelay
toImageDecoderDecoder
andGifDecoder
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.
- Fix race condition while converting a drawable with shared state to a bitmap. (#771)
- Fix
ImageLoader.Builder.fallback
setting theerror
drawable instead of thefallback
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.
- Fix
VideoFrameUriFetcher
attempting to handle http/https URIs. (#734
- Important: Use an SVG's view bounds to calculate its aspect ratio in
SvgDecoder
. (#688)- Previously,
SvgDecoder
used an SVG'swidth
/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 yourSvgDecoder
.
- Previously,
- 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.
- 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
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.
- Without this fix bitmap pooling was still disabled properly, however it used a more heavyweight
- 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.
- Fix a case where
ViewSizeResolver.size
could throw anIllegalStateException
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 aNetworkOnMainThreadException
unlessImageRequest.networkCachePolicy
is set toCachePolicy.DISABLED
orCachePolicy.WRITE_ONLY
.
- Requests that are forced to execute on the main thread using
- 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).
- Important: Change the
CENTER
andMATRIX
ImageView
scale 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 aViewSizeResolver
when constructing your request.
- Important: Return the display size from
ViewSizeResolver
if 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.Factory
a functional interface. (#575) - Stabilize
EventListener
. (#574) - Add
String
overload forImageRequest.Builder.placeholderMemoryCacheKey
. - Add
@JvmOverloads
to theViewSizeResolver
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).
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.
- 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
- This release requires Kotlin 1.4.0 or above.
- All the changes present in 0.13.0.
- Depend on the base Kotlin
stdlib
instead ofstdlib-jdk8
.
- 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 onImageRequest.dispatcher
, setImageLoader.Builder.launchInterceptorChainOnMainThread(false)
. - See
launchInterceptorChainOnMainThread
for more information.
- This largely restores the behaviour from
- 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
andblockSizeLong
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 aFile
.
- Update Kotlin to 1.4.0.
- Update Coroutines to 1.3.9.
- Update Okio to 2.8.0.
- 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.
- See here for how to enable
- Remove all existing deprecated methods in 0.12.0.
- Update Coroutines to 1.3.9.
- Breaking:
LoadRequest
andGetRequest
have been replaced withImageRequest
:ImageLoader.execute(LoadRequest)
->ImageLoader.enqueue(ImageRequest)
ImageLoader.execute(GetRequest)
->ImageLoader.execute(ImageRequest)
ImageRequest
implementsequals
/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 implementsViewTarget
. - Breaking:
ImageRequest.Listener.onSuccess
's signature has changed to return anImageResult.Metadata
instead 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
Interceptor
s 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:
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 theMemoryCache.Key
of a previous request as theplaceholderMemoryCacheKey
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).
- The
- Important: Coil's
ImageView
extension functions have been moved from thecoil.api
package to thecoil
package.- Use find + replace to refactor
import coil.api.load
->import coil.load
. Unfortunately, it's not possible to use Kotlin'sReplaceWith
functionality 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:
MeasuredMapper
has been deprecated in favour of the newInterceptor
interface. See here for an example of how to convert aMeasuredMapper
into anInterceptor
.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 anImageRequest
without setting its data it will returnNullRequestData
as its data.
- New: Add support for direct read/write access to an
ImageLoader
'sMemoryCache
. See the docs for more information. - New: Add support for
Interceptor
s. See the docs for more information. Coil'sInterceptor
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
).
- 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
- Breaking: This version removes all existing deprecated functions.
- This enables removing Coil's
ContentProvider
so it doesn't run any code at app startup.
- This enables removing Coil's
- 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 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.
- 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.
-
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:coil
artifact, you can callCoil.execute(request)
to execute the request with the singletonImageLoader
.
- If you're using the
-
ImageLoader
s 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
Application
to simplify singleton initialization.
- Important: Deprecate DSL syntax in favour of builder syntax. (#267)
- Important: Deprecate
Coil
andImageLoader
extension functions. (#322) - Breaking: Return sealed
RequestResult
type fromImageLoader.execute(GetRequest)
. (#349) - Breaking: Rename
ExperimentalCoil
toExperimentalCoilApi
. Migrate from@Experimental
to@RequiresOptIn
. (#306) - Breaking: Replace
CoilLogger
withLogger
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 fullRequest
object instead of just its data. - Breaking:
GetRequestBuilder
now requires aContext
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 afterTarget.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
andfallback
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 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
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
- 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
- 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 aRGBA_F16
bitmap returned to you from the memory cache. Now, the cached config and the requested config must be equal. - Make
scale
anddurationMillis
public inCrossfadeDrawable
andCrossfadeTransition
.
- 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
- 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.
- Fix: Fix crash when calling
LoadRequestBuilder.crossfade(false)
.
- Breaking:
Transformation.transform
now includes aSize
parameter. This is to support transformations that change the size of the outputBitmap
based on the size of theTarget
. Requests with transformations are now also exempt from image sampling. - Breaking:
Transformation
s are now applied to any type ofDrawable
. Before,Transformation
s would be skipped if the inputDrawable
was not aBitmapDrawable
. Now,Drawable
s are rendered to aBitmap
before applying theTransformation
s. - Breaking: Passing
null
data toImageLoader.load
is now treated as an error and callsTarget.onError
andRequest.Listener.onError
with aNullRequestDataException
. This change was made to support setting afallback
drawable if data isnull
. Previously the request was silently ignored. - Breaking:
RequestDisposable.isDisposed
is 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.await
to support suspending while aLoadRequest
is in progress. - New: Support setting a
fallback
drawable when request data is null. - New: Add
Precision
. This makes the size of the outputDrawable
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
- Breaking:
SvgDrawable
has been removed. Instead, SVGs are now prerendered toBitmapDrawable
s bySvgDecoder
. This makes SVGs significantly less expensive to render on the main thread. AlsoSvgDecoder
now requires aContext
in its constructor. - Breaking:
SparseIntArraySet
extension functions have moved to thecoil.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
fromcompileOnly
toimplementation
forcoil-base
.
- 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 customOkHttpClient
you must setOkHttpClient.cache
to enable disk caching. If you don't set a customOkHttpClient
, Coil will create the defaultOkHttpClient
which 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.key
no longer has a default implementation. - Breaking: Previously, only the first applicable
Mapper
would be called. Now, all applicableMapper
s will be called. No API changes. - Breaking: Minor named parameter renaming:
url
->uri
,factory
->initializer
.
- New:
coil-svg
artifact, which has anSvgDecoder
that 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.Factory
instead ofOkHttpClient
. This allows lazy initialization of the networking resources usingImageLoaderBuilder.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.0androidx.core:core-ktx
-> 1.1.0androidx.lifecycle:lifecycle-common-java8
-> 2.1.0
- Replace
appcompat
withappcompat-resources
as an optionalcompileOnly
dependency.appcompat-resources
is a much smaller artifact.
- 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.
- Initial release.