### Paparazzi Test Setup with Fake Engine Source: https://github.com/coil-kt/coil/blob/main/coil-test/README.md Integrate FakeImageLoaderEngine with Paparazzi for UI snapshot testing. This sets up a mocked ImageLoader before each test. ```kotlin class PaparazziTest { @get:Rule val paparazzi = Paparazzi() @Before fun before() { val engine = FakeImageLoaderEngine.Builder() .intercept("https://example.com/image.jpg", ColorImage(Color.Red.toArgb())) .intercept({ it is String && it.endsWith("test.png") }, ColorImage(Color.Green.toArgb())) .default(ColorImage(Color.Blue.toArgb())) .build() val imageLoader = ImageLoader.Builder(paparazzi.context) .components { add(engine) } .build() SingletonImageLoader.setUnsafe(imageLoader) } @Test fun testContentComposeRed() { // Will display a red box. paparazzi.snapshot { AsyncImage( model = "https://example.com/image.jpg", contentDescription = null, ) } } @Test fun testContentComposeGreen() { // Will display a green box. paparazzi.snapshot { AsyncImage( model = "https://www.example.com/test.png", contentDescription = null, ) } } @Test fun testContentComposeBlue() { // Will display a blue box. paparazzi.snapshot { AsyncImage( model = "https://www.example.com/default.png", contentDescription = null, ) } } } ``` -------------------------------- ### Loading into Non-View Targets Source: https://github.com/coil-kt/coil/blob/main/docs/migrating.md Illustrates how to load an image into a target that is not an ImageView, including handling callbacks for start, success, and error states. ```kotlin // Glide (has optional callbacks for start and error) Glide.with(context) .load(url) .into(object : CustomTarget() { override fun onResourceReady(resource: Drawable, transition: Transition) { // Handle the successful result. } override fun onLoadCleared(placeholder: Drawable) { // Remove the drawable provided in onResourceReady from any Views and ensure no references to it remain. } }) // Picasso Picasso.get() .load(url) .into(object : BitmapTarget { override fun onBitmapLoaded(bitmap: Bitmap, from: Picasso.LoadedFrom) { // Handle the successful result. } override fun onBitmapFailed(e: Exception, errorDrawable: Drawable?) { // Handle the error drawable. } override fun onPrepareLoad(placeHolderDrawable: Drawable?) { // Handle the placeholder drawable. } }) // Coil val request = ImageRequest.Builder(context) .data(url) .target( onStart = { placeholder -> // Handle the placeholder image. }, onSuccess = { result -> // Handle the successful result. }, onError = { error -> // Handle the error image. } ) .build() context.imageLoader.enqueue(request) ``` -------------------------------- ### Advanced AsyncImage with ImageRequest Source: https://github.com/coil-kt/coil/blob/main/coil-compose/README.md Load an image with custom configurations like crossfade, placeholder, content scale, and modifiers. This example uses an ImageRequest.Builder for more control. ```kotlin 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), ) ``` -------------------------------- ### Load Image with Coil 1.x rememberImagePainter Source: https://github.com/coil-kt/coil/blob/main/docs/upgrading_to_coil2.md Example of loading an image using `rememberImagePainter` in Coil 1.x, including crossfade configuration. ```kotlin val painter = rememberImagePainter("https://example.com/image.jpg") { crossfade(true) } Image( painter = painter, contentDescription = null, contentScale = ContentScale.Crop ) ``` -------------------------------- ### Implement Custom Transitions in Compose Source: https://github.com/coil-kt/coil/blob/main/coil-compose/README.md Create custom transitions in Compose by observing the AsyncImagePainter.state. This example shows how to trigger an animation when the image state is Success and the data source is not the memory cache. ```kotlin val painter = rememberAsyncImagePainter("https://example.com/image.jpg") val state by painter.state.collectAsState() if (state is AsyncImagePainter.State.Success && state.result.dataSource != DataSource.MEMORY_CACHE) { // Perform the transition animation. } Image( painter = painter, contentDescription = stringResource(R.string.description), ) ``` -------------------------------- ### Implementing a Custom Cache Interceptor Source: https://github.com/coil-kt/coil/blob/main/docs/image_pipeline.md Create a custom `Interceptor` to add a cache layer to the image pipeline. This example shows how to check a memory cache before proceeding. ```kotlin class CustomCacheInterceptor( private val context: Context, private val cache: LruCache, ) : Interceptor { override suspend fun intercept(chain: Interceptor.Chain): ImageResult { val value = cache.get(chain.request.data.toString()) if (value != null) { return SuccessResult( image = value.bitmap.toImage(), request = chain.request, dataSource = DataSource.MEMORY_CACHE, ) } return chain.proceed(chain.request) } } ``` -------------------------------- ### Get Singleton ImageLoader in Java Source: https://github.com/coil-kt/coil/blob/main/docs/java_compatibility.md Use this method to retrieve the singleton ImageLoader instance in Java. Ensure you have the Android context available. ```java ImageLoader imageLoader = SingletonImageLoader.get(context); ``` -------------------------------- ### Execute Image Synchronously in Java Source: https://github.com/coil-kt/coil/blob/main/docs/java_compatibility.md To get an image synchronously from Java, use the ImageLoaders.executeBlocking extension function. This function blocks the current thread, so avoid calling it on the main thread. It returns an Image object which can be converted to a Drawable. ```java ImageRequest request = new ImageRequest.Builder(context) .data("https://example.com/image.jpg") .size(1080, 1920) .build(); Image image = ImageLoaders.executeBlocking(imageLoader, request).getImage(); Drawable drawable = Image_androidKt.asDrawable(image, context. resources); ``` -------------------------------- ### Get Pixel Value from Dimension Source: https://github.com/coil-kt/coil/blob/main/docs/upgrading_to_coil2.md Use the `pxOrElse` extension to retrieve the pixel value of a Dimension, providing a fallback if it's undefined. ```kotlin val width = size.width.pxOrElse { -1 } if (width > 0) { // Use the pixel value. } ``` -------------------------------- ### Tagging the release Source: https://github.com/coil-kt/coil/blob/main/RELEASING.md Create a git tag for the new version. ```bash $ git tag X.Y.Z ``` -------------------------------- ### Configure Singleton ImageLoader Source: https://github.com/coil-kt/coil/blob/main/docs/image_loaders.md Methods for setting up a singleton ImageLoader, including safe, factory, unsafe, and Application-level implementation patterns. ```kotlin // The setSafe method ensures that it won't overwrite an // existing image loader that's been created. SingletonImageLoader.setSafe { ImageLoader.Builder(context) .crossfade(true) .build() } // An alias of SingletonImageLoader.setSafe that's useful for // Compose Multiplatform apps. setSingletonImageLoaderFactory { context -> ImageLoader.Builder(context) .crossfade(true) .build() } // Should only be used in tests. If you call this method // multiple times it will create multiple image loaders. SingletonImageLoader.setUnsafe { ImageLoader.Builder(context) .crossfade(true) .build() } // On Android you can implement SingletonImageLoader.Factory on your // Application class to have it create the singleton image loader. class CustomApplication : SingletonImageLoader.Factory { override fun newImageLoader(context: Context): ImageLoader { return ImageLoader.Builder(context) .crossfade(true) .build() } } ``` -------------------------------- ### Configure Disk Cache in Coil 1.x Source: https://github.com/coil-kt/coil/blob/main/docs/upgrading_to_coil2.md Shows how to configure the disk cache in Coil 1.x using OkHttp's cache and `CoilUtils.createDefaultCache`. ```kotlin ImageLoader.Builder(context) .okHttpClient { OkHttpClient.Builder().cache(CoilUtils.createDefaultCache(context)).build() } .build() ``` -------------------------------- ### Publishing the artifact Source: https://github.com/coil-kt/coil/blob/main/RELEASING.md Execute the remote publishing script to deploy the library. ```bash $ ./publish_remote.sh ``` -------------------------------- ### Custom Image Loading with Placeholders and FitCenter Source: https://github.com/coil-kt/coil/blob/main/docs/migrating.md Demonstrates how to load an image with a placeholder and apply center fitting. Coil automatically handles scale type detection. ```kotlin imageView.scaleType = ImageView.ScaleType.FIT_CENTER // Glide Glide.with(context) .load(url) .placeholder(placeholder) .fitCenter() .into(imageView) // Picasso Picasso.get() .load(url) .placeholder(placeholder) .fit() .into(imageView) // Coil (automatically detects the scale type) imageView.load(url) { placeholder(placeholder) } ``` -------------------------------- ### Configure Disk Cache in Coil 2.x Source: https://github.com/coil-kt/coil/blob/main/docs/upgrading_to_coil2.md Illustrates configuring the disk cache in Coil 2.x using `DiskCache.Builder` directly within the `ImageLoader.Builder`. ```kotlin ImageLoader.Builder(context) .diskCache { DiskCache.Builder() .directory(context.cacheDir.resolve("image_cache")) .build() } .build() ``` -------------------------------- ### Configure Singleton ImageLoader with Crossfade (Compose Multiplatform) Source: https://github.com/coil-kt/coil/blob/main/docs/getting_started.md Set a custom singleton ImageLoader factory for Compose Multiplatform apps, enabling crossfade animations. ```kotlin setSingletonImageLoaderFactory { context -> ImageLoader.Builder(context) .crossfade(true) .build() } ``` -------------------------------- ### Add Network Support with Ktor 3 Source: https://github.com/coil-kt/coil/blob/main/coil-network-core/README.md Import this dependency to enable network image loading with Ktor 3. ```kotlin implementation("io.coil-kt.coil3:coil-network-ktor3:3.5.0") ``` -------------------------------- ### Add Network Support with Ktor 2 Source: https://github.com/coil-kt/coil/blob/main/coil-network-core/README.md Import this dependency to enable network image loading with Ktor 2. ```kotlin implementation("io.coil-kt.coil3:coil-network-ktor2:3.5.0") ``` -------------------------------- ### Basic Image Loading Source: https://github.com/coil-kt/coil/blob/main/docs/migrating.md Shows the basic syntax for loading an image into an ImageView using Glide, Picasso, and Coil. ```kotlin // Glide Glide.with(context) .load(url) .into(imageView) // Picasso Picasso.get() .load(url) .into(imageView) // Coil imageView.load(url) ``` -------------------------------- ### Add Network Support with OkHttp Source: https://github.com/coil-kt/coil/blob/main/coil-network-core/README.md Import this dependency to enable network image loading with OkHttp. Only available on Android/JVM. ```kotlin implementation("io.coil-kt.coil3:coil-network-okhttp:3.5.0") ``` -------------------------------- ### Implement a Chaining Fetcher Source: https://github.com/coil-kt/coil/blob/main/docs/image_pipeline.md Create a Fetcher that performs an initial operation and delegates the final loading to an internal component. ```kotlin class PartialUrlFetcher( private val callFactory: Call.Factory, private val partialUrl: PartialUrl, private val options: Options, private val imageLoader: ImageLoader, ) : Fetcher { override suspend fun fetch(): FetchResult? { val request = Request.Builder() .url(partialUrl.baseUrl) .build() val response = callFactory.newCall(request).await() // Read the image URL. val imageUrl: String = readImageUrl(response.body) // This will delegate to the internal network fetcher. val data = imageLoader.components.map(imageUrl, options) val output = imageLoader.components.newFetcher(data, options, imageLoader) val (fetcher) = checkNotNull(output) { "no supported fetcher" } return fetcher.fetch() } class Factory( private val callFactory: Call.Factory = OkHttpClient(), ) : Fetcher.Factory { override fun create(data: PartialUrl, options: Options, imageLoader: ImageLoader): Fetcher { return PartialUrlFetcher(callFactory, data, options, imageLoader) } } } ``` -------------------------------- ### Committing version preparation Source: https://github.com/coil-kt/coil/blob/main/RELEASING.md Commit the changes made to gradle.properties for the release. ```bash $ git commit -m "Prepare version X.Y.Z." ``` -------------------------------- ### Add Coil Video Dependency Source: https://github.com/coil-kt/coil/blob/main/coil-video/README.md Import the coil-video extension library to enable video frame support. ```kotlin implementation("io.coil-kt.coil3:coil-video:3.5.0") ``` -------------------------------- ### Basic SubcomposeAsyncImage Usage Source: https://github.com/coil-kt/coil/blob/main/coil-compose/README.md Demonstrates the basic usage of SubcomposeAsyncImage with a loading indicator. This is suitable for simple image loading scenarios. ```kotlin SubcomposeAsyncImage( model = "https://example.com/image.jpg", loading = { CircularProgressIndicator() }, contentDescription = stringResource(R.string.description), ) ``` -------------------------------- ### Configure FakeImageLoaderEngine Source: https://github.com/coil-kt/coil/blob/main/coil-test/README.md Set up FakeImageLoaderEngine to intercept ImageRequests and return custom results. This makes image loading synchronous and bypasses network/disk I/O. ```kotlin val engine = FakeImageLoaderEngine.Builder() .intercept("https://example.com/image.jpg", ColorImage(Color.Red.toArgb())) .intercept({ it is String && it.endsWith("test.png") }, ColorImage(Color.Green.toArgb())) .default(ColorImage(Color.Blue.toArgb())) .build() val imageLoader = ImageLoader.Builder(context) .components { add(engine) } .build() ``` -------------------------------- ### Configure ImageLoader Caching Source: https://github.com/coil-kt/coil/blob/main/docs/image_loaders.md Customizing memory and disk cache settings during ImageLoader initialization. ```kotlin val imageLoader = ImageLoader.Builder(context) .memoryCache { MemoryCache.Builder() .maxSizePercent(context, 0.25) .build() } .diskCache { DiskCache.Builder() .directory(context.cacheDir.resolve("image_cache")) .maxSizePercent(0.02) .build() } .build() ``` -------------------------------- ### Convert Image to Compose Painter Source: https://github.com/coil-kt/coil/blob/main/docs/getting_started.md Convert a coil3.Image to a Compose UI Painter. Requires importing the coil-compose-core artifact. ```kotlin val painter = image.asPainter() ``` -------------------------------- ### Load Image with Coil 2.x rememberAsyncImagePainter Source: https://github.com/coil-kt/coil/blob/main/docs/upgrading_to_coil2.md Demonstrates loading an image with `rememberAsyncImagePainter` in Coil 2.x, including model configuration and content scale. ```kotlin val painter = rememberAsyncImagePainter( model = ImageRequest.Builder(LocalContext.current) .data("https://example.com/image.jpg") .crossfade(true) .build(), contentScale = ContentScale.Crop ) Image( painter = painter, contentDescription = null, contentScale = ContentScale.Crop ) ``` -------------------------------- ### Loading Compose Multiplatform Resources Source: https://github.com/coil-kt/coil/blob/main/coil-compose/README.md Load Compose Multiplatform resources by using `Res.getUri` as the model parameter for AsyncImage. Note that compile-safe references like `Res.drawable.image` are not directly supported. ```kotlin AsyncImage( model = Res.getUri("drawable/sample.jpg"), contentDescription = null, ) ``` -------------------------------- ### Configure Singleton ImageLoader with Crossfade (Flexible) Source: https://github.com/coil-kt/coil/blob/main/docs/getting_started.md Use SingletonImageLoader.setSafe to configure a custom ImageLoader with crossfade, offering flexibility for app entry points. ```kotlin SingletonImageLoader.setSafe { context -> ImageLoader.Builder(context) .crossfade(true) .build() } ``` -------------------------------- ### Add Coil Compose and OkHttp Dependencies Source: https://github.com/coil-kt/coil/blob/main/README.md Import the Coil Compose library and the OkHttp networking library to enable image loading in your Android or Compose Multiplatform application. ```kotlin implementation("io.coil-kt.coil3:coil-compose:3.5.0") implementation("io.coil-kt.coil3:coil-network-okhttp:3.5.0") ``` -------------------------------- ### Load an Image with AsyncImage Source: https://github.com/coil-kt/coil/blob/main/README.md Use the AsyncImage composable to load and display an image from a URL. Set the 'model' parameter to the image URL and 'contentDescription' for accessibility. ```kotlin AsyncImage( model = "https://example.com/image.jpg", contentDescription = null, ) ``` -------------------------------- ### Configure Custom OkHttpClient for ImageLoader Source: https://github.com/coil-kt/coil/blob/main/coil-network-core/README.md Specify a custom OkHttpClient when creating an ImageLoader to integrate with coil-network-okhttp. A new OkHttpClient is created within the components block. ```kotlin val imageLoader = ImageLoader.Builder(context) .components { add( OkHttpNetworkFetcherFactory( callFactory = { OkHttpClient() } ) ) } .build() ``` -------------------------------- ### Enqueue ImageRequest in Java Source: https://github.com/coil-kt/coil/blob/main/docs/java_compatibility.md The syntax for enqueuing an ImageRequest in Java is similar to Kotlin. Use the ImageRequest.Builder to construct the request and then enqueue it with the ImageLoader. ```java ImageRequest request = new ImageRequest.Builder(context) .data("https://example.com/image.jpg") .crossfade(true) .target(new ImageViewTarget(imageView)) .build(); imageLoader.enqueue(request); ``` -------------------------------- ### Loading an Image Using a Custom Data Model Source: https://github.com/coil-kt/coil/blob/main/docs/image_pipeline.md After registering a custom `Mapper`, you can load images directly using your custom data models. ```kotlin val request = ImageRequest.Builder(context) .data(item) .target(imageView) .build() imageLoader.enqueue(request) ``` -------------------------------- ### Loading Images on a Background Thread Source: https://github.com/coil-kt/coil/blob/main/docs/migrating.md Shows how to load an image on a background thread. Glide and Picasso block the current thread, while Coil uses a suspending function for non-blocking execution. ```kotlin // Glide (blocks the current thread; must not be called from the main thread) val drawable = Glide.with(context) .load(url) .submit(width, height) .get() // Picasso (blocks the current thread; must not be called from the main thread) val drawable = Picasso.get() .load(url) .resize(width, height) .get() // Coil (suspends, non-blocking, and thread safe) val request = ImageRequest.Builder(context) .data(url) .size(width, height) .build() val drawable = context.imageLoader.execute(request).image.asDrawable(resources) ``` -------------------------------- ### Load Image with SizeResolver Source: https://github.com/coil-kt/coil/blob/main/coil-compose/README.md This snippet demonstrates how to use `rememberAsyncImagePainter` with a custom `SizeResolver` to ensure the image is loaded with appropriate dimensions, preventing it from always using its original size. It also shows how to integrate the `SizeResolver` with the `Image` composable. ```kotlin val sizeResolver = rememberConstraintsSizeResolver() val painter = rememberAsyncImagePainter( model = ImageRequest.Builder(LocalPlatformContext.current) .data("https://example.com/image.jpg") .size(sizeResolver) .build(), ) Image( painter = painter, contentDescription = null, modifier = Modifier.then(sizeResolver), ) ``` -------------------------------- ### Committing development version Source: https://github.com/coil-kt/coil/blob/main/RELEASING.md Commit the update to the next SNAPSHOT version in gradle.properties. ```bash $ git commit -m "Prepare next development version." ``` -------------------------------- ### SubcomposeAsyncImage with Custom Content Logic Source: https://github.com/coil-kt/coil/blob/main/coil-compose/README.md Shows how to use SubcomposeAsyncImage with a custom content lambda to conditionally render content based on the painter's state. This allows for more complex UI logic during image loading. ```kotlin SubcomposeAsyncImage( model = "https://example.com/image.jpg", contentDescription = stringResource(R.string.description) ) { val state by painter.state.collectAsState() if (state is AsyncImagePainter.State.Success) { SubcomposeAsyncImageContent() } else { CircularProgressIndicator() } } ``` -------------------------------- ### Use Cache-Control Strategy with OkHttpNetworkFetcherFactory Source: https://github.com/coil-kt/coil/blob/main/coil-network-core/README.md Configure OkHttpNetworkFetcherFactory to respect Cache-Control headers by providing CacheControlCacheStrategy. This ensures network responses are cached according to their Cache-Control directives. ```kotlin OkHttpNetworkFetcherFactory( cacheStrategy = { CacheControlCacheStrategy() }, ) ``` -------------------------------- ### Pushing changes and tags Source: https://github.com/coil-kt/coil/blob/main/RELEASING.md Push commits and tags to the remote repository. ```bash $ git push && git push --tags ``` -------------------------------- ### Configure ImageLoader with VideoFrameDecoder Source: https://github.com/coil-kt/coil/blob/main/coil-video/README.md Add the VideoFrameDecoder.Factory to your ImageLoader's component registry to enable video frame decoding. ```kotlin val imageLoader = ImageLoader.Builder(context) .components { add(VideoFrameDecoder.Factory()) } .build() ``` -------------------------------- ### Ktor Network Engines for JVM Source: https://github.com/coil-kt/coil/blob/main/coil-network-core/README.md Add the Ktor Java client engine when using coil-network-ktor2 or coil-network-ktor3 for JVM development. ```kotlin jvmMain { dependencies { implementation("io.ktor:ktor-client-java:") } } ``` -------------------------------- ### Configure Singleton ImageLoader with Crossfade (Android App) Source: https://github.com/coil-kt/coil/blob/main/docs/getting_started.md Implement SingletonImageLoader.Factory in your Android Application class to configure a custom ImageLoader with crossfade enabled. ```kotlin class CustomApplication : Application(), SingletonImageLoader.Factory { override fun newImageLoader(context: Context): ImageLoader { return ImageLoader.Builder(context) .crossfade(true) .build() } } ``` -------------------------------- ### Ktor Network Engines for Apple Platforms Source: https://github.com/coil-kt/coil/blob/main/coil-network-core/README.md Add the Ktor Darwin client engine when using coil-network-ktor2 or coil-network-ktor3 for Apple platform development. ```kotlin appleMain { dependencies { implementation("io.ktor:ktor-client-darwin:") } } ``` -------------------------------- ### Load Image with rememberAsyncImagePainter Source: https://github.com/coil-kt/coil/blob/main/coil-compose/README.md Use this snippet to load an image as a Painter using its URL. This is useful when you need a Painter object directly or need to observe the painter's state. ```kotlin val painter = rememberAsyncImagePainter("https://example.com/image.jpg") ``` -------------------------------- ### Specify Video Frame by Percentage Source: https://github.com/coil-kt/coil/blob/main/coil-video/README.md Use videoFramePercent to extract a frame based on a percentage of the video's total duration. ```kotlin imageView.load("/path/to/video.mp4") { videoFramePercent(0.5) // extracts the frame in the middle of the video's duration } ``` -------------------------------- ### Observe AsyncImagePainter State Source: https://github.com/coil-kt/coil/blob/main/coil-compose/README.md Observe the state of AsyncImagePainter to display different UI elements based on the loading status (Empty, Loading, Success, Error). Requires collecting the state as StateFlow. ```kotlin val painter = rememberAsyncImagePainter("https://example.com/image.jpg") val state by painter.state.collectAsState() when (state) { is AsyncImagePainter.State.Empty, is AsyncImagePainter.State.Loading -> { CircularProgressIndicator() } is AsyncImagePainter.State.Success -> { Image( painter = painter, contentDescription = stringResource(R.string.description) ) } is AsyncImagePainter.State.Error -> { // Show some error UI. } } ``` -------------------------------- ### Define Custom Extras for ImageRequest and ImageLoader Source: https://github.com/coil-kt/coil/blob/main/docs/image_pipeline.md Use Extras to store custom properties like timeouts. Keys must be declared statically for instance equality comparison. ```kotlin fun ImageRequest.Builder.timeout(timeout: Duration) = apply { extras[timeoutKey] = timeout } fun ImageLoader.Builder.timeout(timeout: Duration) = apply { extras[timeoutKey] = timeout } val ImageRequest.timeout: Duration get() = getExtra(timeoutKey) val Options.timeout: Duration get() = getExtra(timeoutKey) // NOTE: Extras.Key instances should be declared statically as they're compared with instance equality. private val timeoutKey = Extras.Key(default = Duration.INFINITE) ``` -------------------------------- ### Load Network Image in Android Views Source: https://github.com/coil-kt/coil/blob/main/docs/getting_started.md Load an image from a network URL into an ImageView using the Coil extension function. ```kotlin imageView.load("https://example.com/image.jpg") ``` -------------------------------- ### Use Memory Cache Key as Placeholder Source: https://github.com/coil-kt/coil/blob/main/docs/recipes.md Set the placeholderMemoryCacheKey of a new request to the result of a previous request to enable seamless image transitions. ```kotlin // First request listImageView.load("https://example.com/image.jpg") // Second request (once the first request finishes) detailImageView.load("https://example.com/image.jpg") { placeholderMemoryCacheKey(listImageView.result.memoryCacheKey) } ``` -------------------------------- ### Create an ImageRequest Source: https://github.com/coil-kt/coil/blob/main/docs/image_requests.md Use the ImageRequest.Builder to construct a request with data, crossfade, and target. In Coil 3.x, platform-specific functions like target(ImageView) are extension functions and require separate imports. ```kotlin val request = ImageRequest.Builder(context) .data("https://example.com/image.jpg") .crossfade(true) .target(imageView) .build() ``` -------------------------------- ### Enable Built-in Crossfade Transition Source: https://github.com/coil-kt/coil/blob/main/coil-compose/README.md Enable the built-in crossfade transition for images loaded with AsyncImage by using the ImageRequest.Builder.crossfade modifier. ```kotlin AsyncImage( model = ImageRequest.Builder(LocalContext.current) .data("https://example.com/image.jpg") .crossfade(true) .build(), contentDescription = null, ) ``` -------------------------------- ### Configure Max Bitmap Size Source: https://github.com/coil-kt/coil/blob/main/docs/upgrading_to_coil3.md The maximum output image dimensions can be configured using `maxBitmapSize` on `ImageLoader.Builder` or `ImageRequest.Builder`. Set to `Size.ORIGINAL` to disable the limit. ```kotlin ImageLoader.Builder(context).maxBitmapSize(4096, 4096).build() ``` ```kotlin ImageRequest.Builder(context, uri).maxBitmapSize(Size.ORIGINAL).build() ``` -------------------------------- ### Mapping Custom Data Models to URLs Source: https://github.com/coil-kt/coil/blob/main/docs/image_pipeline.md Implement a `Mapper` to convert a custom data model (e.g., `Item`) into a URL string that Coil can use for fetching. ```kotlin data class Item( val id: Int, val imageUrl: String, val price: Int, val weight: Double ) ``` ```kotlin class ItemMapper : Mapper { override fun map(data: Item, options: Options) = data.imageUrl } ``` -------------------------------- ### Manually Configure GIF Decoders Source: https://github.com/coil-kt/coil/blob/main/coil-gif/README.md Optionally, manually add GIF decoders to your ImageLoader. Use AnimatedImageDecoder for API 28+ for better performance, otherwise use GifDecoder. ```kotlin val imageLoader = ImageLoader.Builder(context) .components { if (SDK_INT >= 28) { add(AnimatedImageDecoder.Factory()) } else { add(GifDecoder.Factory()) } } .build() ``` -------------------------------- ### Extract Palette Colors from Image Source: https://github.com/coil-kt/coil/blob/main/docs/recipes.md Use an ImageRequest.Listener to access the bitmap and generate a Palette. Hardware bitmaps must be disabled as Palette requires software-accessible pixels. ```kotlin imageView.load("https://example.com/image.jpg") { // Disable hardware bitmaps as Palette needs to read the image's pixels. allowHardware(false) listener( onSuccess = { _, result -> // Create the palette on a background thread. Palette.Builder(result.image.toBitmap()).generate { palette -> // Consume the palette. } } ) } ``` -------------------------------- ### Apply transformations to a painter Source: https://github.com/coil-kt/coil/blob/main/docs/recipes.md Wraps a painter using forwardingPainter to apply color filters or alpha adjustments. ```kotlin AsyncImage( model = "https://example.com/image.jpg", contentDescription = null, placeholder = forwardingPainter( painter = painterResource(R.drawable.placeholder), colorFilter = ColorFilter(Color.Red), alpha = 0.5f, ), ) ``` -------------------------------- ### Implement a custom Interceptor Source: https://github.com/coil-kt/coil/blob/main/docs/recipes.md Modifies HTTP requests by appending query parameters based on the requested image size. ```kotlin class UrlSizeInterceptor : Interceptor { override suspend fun intercept(chain: Chain): ImageResult { val request = chain.request val uri = request.uri if (uri == null || uri.scheme !in setOf("https", "http")) { // Ignore non-HTTP requests. return chain.proceed() } val (width, height) = chain.size return if (width is Pixels && height is Pixels) { val transformUri = uri.newBuilder() .query("width=${width.px}&height=${height.px}") .build() val transformedRequest = request.newBuilder() .data(transformUri) .build() return chain.withRequest(transformedRequest).proceed() } else { // Width & height aren't available, i.e. because of infinite constraints. chain.proceed() } } private val ImageRequest.uri: Uri? get() = when (val data = data) { is Uri -> data is coil3.Uri -> data.toAndroidUri() is String -> data.toUri() else -> null } } ``` -------------------------------- ### Registering Custom Components with ImageLoader Source: https://github.com/coil-kt/coil/blob/main/docs/image_pipeline.md Use the `components` block in `ImageLoader.Builder` to add custom Interceptors, Mappers, Keyers, Fetchers, and Decoders. ```kotlin val imageLoader = ImageLoader.Builder(context) .components { add(CustomCacheInterceptor()) add(ItemMapper()) add(HttpUrlKeyer()) add(CronetFetcher.Factory()) add(GifDecoder.Factory()) } .build() ``` -------------------------------- ### Enqueue an ImageRequest Source: https://github.com/coil-kt/coil/blob/main/docs/image_requests.md Pass the created ImageRequest to an ImageLoader to enqueue or execute the image loading operation. ```kotlin imageLoader.enqueue(request) ``` -------------------------------- ### Add Global HTTP Headers with OkHttp Interceptor Source: https://github.com/coil-kt/coil/blob/main/coil-network-core/README.md Implement an OkHttp Interceptor to add headers like 'Cache-Control' to all requests made by the ImageLoader. This is useful for applying consistent headers across all network operations. ```kotlin class RequestHeaderInterceptor( private val name: String, private val value: String, ) : Interceptor { override fun intercept(chain: Interceptor.Chain): Response { val headers = Headers.Builder() .set("Cache-Control", "no-cache") .build() val request = chain.request().newBuilder() .headers(headers) .build() return chain.proceed(request) } } val imageLoader = ImageLoader.Builder(context) .components { add( OkHttpNetworkFetcher( callFactory = { OkHttpClient.Builder() // This header will be added to every image request. .addNetworkInterceptor(RequestHeaderInterceptor("Cache-Control", "no-cache")) .build() }, ) ) } .build() ``` -------------------------------- ### Convert Bitmap to Image Source: https://github.com/coil-kt/coil/blob/main/docs/getting_started.md Convert a platform-specific Bitmap to a coil3.Image. This is useful for multiplatform rendering. ```kotlin val image = bitmap.asImage() ``` -------------------------------- ### Add Coil Compose Dependency Source: https://github.com/coil-kt/coil/blob/main/coil-compose/README.md Add this dependency to your app's build.gradle file to enable Coil support for Compose UI. ```gradle implementation("io.coil-kt.coil3:coil-compose:3.5.0") ``` -------------------------------- ### Add Coil Android Views Dependency Source: https://github.com/coil-kt/coil/blob/main/docs/getting_started.md Add the Coil core and OkHttp network dependencies for use with Android Views. ```kotlin implementation("io.coil-kt.coil3:coil:3.5.0") implementation("io.coil-kt.coil3:coil-network-okhttp:3.5.0") ``` -------------------------------- ### Implement Custom RemoteViews Target Source: https://github.com/coil-kt/coil/blob/main/docs/recipes.md Create a custom Target to update RemoteViews with loaded images. This requires manual updates to the AppWidgetManager. ```kotlin class RemoteViewsTarget( private val context: Context, private val componentName: ComponentName, private val remoteViews: RemoteViews, @IdRes private val imageViewResId: Int ) : Target { override fun onStart(placeholder: Image?) = setImage(placeholder) override fun onError(error: Image?) = setImage(error) override fun onSuccess(result: Image) = setImage(result) private fun setImage(image: Image?) { remoteViews.setImageViewBitmap(imageViewResId, image?.toBitmap()) AppWidgetManager.getInstance(context).updateAppWidget(componentName, remoteViews) } } ``` ```kotlin val request = ImageRequest.Builder(context) .data("https://example.com/image.jpg") .target(RemoteViewsTarget(context, componentName, remoteViews, imageViewResId)) .build() imageLoader.enqueue(request) ``` -------------------------------- ### Apply Custom Properties in AsyncImage Source: https://github.com/coil-kt/coil/blob/main/docs/image_pipeline.md Set custom properties on an ImageRequest using the builder extension functions. ```kotlin AsyncImage( model = ImageRequest.Builder(PlatformContext.current) .data("https://example.com/image.jpg") .timeout(10.seconds) .build(), contentDescription = null, ) ``` -------------------------------- ### Set HTTP Headers for a Single Image Request Source: https://github.com/coil-kt/coil/blob/main/coil-network-core/README.md Add custom HTTP headers, such as 'Cache-Control', to a specific image request using NetworkHeaders.Builder. This allows fine-grained control over request behavior. ```kotlin val headers = NetworkHeaders.Builder() .set("Cache-Control", "no-cache") .build() val request = ImageRequest.Builder(context) .data("https://example.com/image.jpg") .httpHeaders(headers) .target(imageView) .build() imageLoader.execute(request) ``` -------------------------------- ### Customizing Coil Compose Previews Source: https://github.com/coil-kt/coil/blob/main/coil-compose/README.md Override the default preview behavior by providing a custom AsyncImagePreviewHandler. This is useful for controlling how images are displayed in Android Studio previews, especially when network access is unavailable. ```kotlin val previewHandler = AsyncImagePreviewHandler { ColorImage(Color.Red.toArgb()) } CompositionLocalProvider(LocalAsyncImagePreviewHandler provides previewHandler) { AsyncImage( model = "https://example.com/image.jpg", contentDescription = null, ) } ``` -------------------------------- ### Add Coil Test Dependency Source: https://github.com/coil-kt/coil/blob/main/coil-test/README.md Add the coil-test extension library to your project's dependencies to enable testing support. ```kotlin testImplementation("io.coil-kt.coil3:coil-test:3.5.0") ``` -------------------------------- ### Add GIF Extension Dependency Source: https://github.com/coil-kt/coil/blob/main/coil-gif/README.md Add this dependency to your app's build.gradle file to enable GIF support in Coil. ```kotlin implementation("io.coil-kt.coil3:coil-gif:3.5.0") ``` -------------------------------- ### Ktor Network Engines for Android Source: https://github.com/coil-kt/coil/blob/main/coil-network-core/README.md Add the Ktor Android client engine when using coil-network-ktor2 or coil-network-ktor3 for Android development. ```kotlin androidMain { dependencies { implementation("io.ktor:ktor-client-android:") } } ``` -------------------------------- ### Explicitly Set Decoder for Request Source: https://github.com/coil-kt/coil/blob/main/coil-video/README.md If the request's filename/URI does not have a valid video extension, you can explicitly set the Decoder for the request using decoderFactory. ```kotlin imageView.load("/path/to/video") { decoderFactory { result, options, _ -> VideoFrameDecoder(result.source, options) } } ``` -------------------------------- ### Convert Image to Bitmap Source: https://github.com/coil-kt/coil/blob/main/docs/getting_started.md Convert a coil3.Image to a platform-specific Bitmap. This alias works on Android and non-Android platforms. ```kotlin val bitmap = image.toBitmap() ``` -------------------------------- ### Convert Drawable to Image Source: https://github.com/coil-kt/coil/blob/main/docs/getting_started.md Convert an Android Drawable to a coil3.Image. This is useful for multiplatform rendering. ```kotlin val image = drawable.asImage() ``` -------------------------------- ### Convert Image to Drawable Source: https://github.com/coil-kt/coil/blob/main/docs/getting_started.md Convert a coil3.Image to an Android Drawable. Requires Android resources. ```kotlin val drawable = image.asDrawable(resources) ``` -------------------------------- ### Define a Custom Data Type for Chaining Source: https://github.com/coil-kt/coil/blob/main/docs/image_pipeline.md Create a custom data class to be handled by a specialized Fetcher. ```kotlin data class PartialUrl( val baseUrl: String, ) ``` -------------------------------- ### Specify Video Frame by Index Source: https://github.com/coil-kt/coil/blob/main/coil-video/README.md Use videoFrameIndex to extract a specific frame by its frame number. Requires API level 28. ```kotlin imageView.load("/path/to/video.mp4") { videoFrameIndex(1234) // extracts the 1234th frame of the video } ``` -------------------------------- ### Add Coil SVG Dependency Source: https://github.com/coil-kt/coil/blob/main/coil-svg/README.md Add the coil-svg extension library to your project's dependencies to enable SVG support. ```kotlin implementation("io.coil-kt.coil3:coil-svg:3.5.0") ``` -------------------------------- ### Specify Video Frame by Milliseconds Source: https://github.com/coil-kt/coil/blob/main/coil-video/README.md Use videoFrameMillis to extract a specific frame from a video based on its timestamp in milliseconds. ```kotlin imageView.load("/path/to/video.mp4") { videoFrameMillis(1000) // extracts the frame at 1 second of the video } ``` -------------------------------- ### Register an Interceptor in ImageLoader Source: https://github.com/coil-kt/coil/blob/main/docs/recipes.md Adds the custom interceptor to the ImageLoader configuration. ```kotlin ImageLoader.Builder(context) .components { add(UrlSizeInterceptor()) } .build() ``` -------------------------------- ### Implement a Custom Interceptor for Extras Source: https://github.com/coil-kt/coil/blob/main/docs/image_pipeline.md Read custom properties within an Interceptor to modify request behavior, such as applying a timeout. ```kotlin class TimeoutInterceptor : Interceptor { override suspend fun intercept(chain: Interceptor.Chain): ImageResult { val timeout = chain.request.timeout if (timeout.isFinite()) { return withTimeout(timeout) { chain.proceed(chain.request) } } else { return chain.proceed(chain.request) } } } ``` -------------------------------- ### Add SVG Decoder to Component Registry Source: https://github.com/coil-kt/coil/blob/main/coil-svg/README.md Optionally, add the SvgDecoder.Factory to your ImageLoader's component registry during its construction for global SVG support. ```kotlin val imageLoader = ImageLoader.Builder(context) .components { add(SvgDecoder.Factory()) } .build() ``` -------------------------------- ### Disable Service Loader in ImageLoader Source: https://github.com/coil-kt/coil/blob/main/docs/upgrading_to_coil3.md To disable the automatic addition of first-party Fetchers and Decoders via service loader, set `serviceLoaderEnabled` to `false` in the `ImageLoader.Builder`. ```kotlin ImageLoader.Builder(context).serviceLoaderEnabled(false).build() ``` -------------------------------- ### Override onDraw for custom painter transformations Source: https://github.com/coil-kt/coil/blob/main/docs/recipes.md Uses a trailing lambda to perform custom drawing operations like insetting the painter. ```kotlin AsyncImage( model = "https://example.com/image.jpg", contentDescription = null, placeholder = forwardingPainter(painterResource(R.drawable.placeholder)) { info -> inset(50f, 50f) { with(info.painter) { draw(size, info.alpha, info.colorFilter) } } }, ) ``` -------------------------------- ### Manually Set SVG Decoder for a Request Source: https://github.com/coil-kt/coil/blob/main/coil-svg/README.md If an SVG is not automatically detected, you can explicitly set the SvgDecoder for a specific image loading request. ```kotlin imageView.load("/path/to/svg") { decoderFactory { result, options, _ -> SvgDecoder(result.source, options) } } ``` -------------------------------- ### Use Custom Data Type in AsyncImage Source: https://github.com/coil-kt/coil/blob/main/docs/image_pipeline.md Pass the custom data type to AsyncImage after registering the corresponding Fetcher. ```kotlin AsyncImage( model = PartialUrl("https://example.com/image.jpg"), contentDescription = null, ) ``` -------------------------------- ### Re-enable Last Modified Timestamp in Cache Key Source: https://github.com/coil-kt/coil/blob/main/docs/upgrading_to_coil3.md To re-enable adding a file's last write timestamp to its cache key, use `addLastModifiedToFileCacheKey(true)` on either the `ImageRequest.Builder` or `ImageLoader.Builder`. ```kotlin ImageRequest.Builder(context, uri).addLastModifiedToFileCacheKey(true).build() ``` ```kotlin ImageLoader.Builder(context).addLastModifiedToFileCacheKey(true).build() ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.