Comments (19)
Just to check if this is already supported? In glide, I can do as below (placeholder -> initial-fast-load -> full-load)
With codes as below
val requestOption = RequestOptions()
.placeholder(R.drawable.placeholder).centerCrop()
Glide.with(this).load(fullImageUrl)
.transition(DrawableTransitionOptions.withCrossFade())
.thumbnail(Glide.with(this)
.load(fastLoadUrl)
.apply(requestOption))
.apply(requestOption)
.into(my_image_view)
Refer to this article https://medium.com/mobile-app-development-publication/glide-image-loader-the-basic-798db220bb44
Hopes Coil
can do the same.
from coil.
can anyone suggest any workaround for the coil to achieve the same?
Here you go. It is used by me in my prod app and no issues/complaints till now. If anyone finds a better solution, please let me know.
from coil.
can anyone suggest any workaround for the coil to achieve the same?
Slight changes to kasem-sm's reply:
fun ImageView.loadWithQuality(
highQuality: String,
lowQuality: String,
placeholderRes: Int? = null,
errorRes: Int? = null
) {
placeholderRes?.let {
setImageResource(placeholderRes)
}
var isHighQualityLoaded = false
class CallbackImageViewTarget(val callback: () -> Boolean) : ImageViewTarget(this) {
override fun onSuccess(result: Drawable) {
if (callback()) {
super.onSuccess(result)
}
}
}
val lowQualityRequest = ImageRequest.Builder(context).apply {
data(lowQuality)
target(CallbackImageViewTarget(
callback = {
return@CallbackImageViewTarget !isHighQualityLoaded
}
))
}.build()
val lowQualityLoader = context.imageLoader.enqueue(lowQualityRequest)
val highQualityRequest = ImageRequest.Builder(context).apply {
data(highQuality)
errorRes?.let { error(errorRes) }
target(CallbackImageViewTarget(
callback = {
isHighQualityLoaded = true
if (!lowQualityLoader.isDisposed) {
lowQualityLoader.dispose()
}
return@CallbackImageViewTarget true
}
))
}.build()
context.imageLoader.enqueue(highQualityRequest)
}
from coil.
Probably the below code works better. Need to test:
fun ImageView.loadWithQuality(
highQuality: String,
lowQuality: String,
placeholderRes: Int? = null,
errorRes: Int? = null
) {
load(lowQuality) {
placeholderRes?.let { placeholder(placeholderRes) }
listener(onSuccess = { _, _ ->
load(highQuality) {
placeholder(drawable) // If there was a way to not clear existing image before loading, this would not be required
errorRes?.let { error(errorRes) }
}
})
}
}
from coil.
Thanks! I've thought about adding a placeholder(data)
method, however have shied away from it so far. Adding it would create more work on the main thread, which could reduce performance. Also, it could result in some unexpected behaviour where you expect something to be in the memory cache and it isn't.
from coil.
Good points. It sounds like what I'm talking about isn't really a "placeholder", because Coil assumes that placeholders are available straight away, synchronously on the main thread. Have I understood that correctly?
Thinking about this overnight, could you do two loads
one-after the other, the first one loading the thumbnail URL but specifying a read only cache policies?
Something like this:
imageView.load(thumbUrl) {
diskCachePolicy = READ_ONLY
networkCachePolicy = DISABLED
placeholder = R.drawable.image_placeholder
crossfade(true) // crossfade from image_placeholder to thumbnail if it loads from disk
}
imageView.load(fullSizeUrl) {
crossfade(true) // crossfade from thumbnail to full image
}
These requests could technically race, which could be a problem in general with this approach. I'm not sure what the desired behaviour even is when you have two loads for the same target. In this example, you want the first load to proceed, but only until the second load completes. But loading into a RecyclerView you want the opposite, where the first load should be cancelled as soon as the view is reused and the second load starts.
from coil.
Ah I see what you mean. This would add a decent chunk of complexity to RealImageLoader
so I'm not sure I'd want to add this in. However, you could create the same effect with get
:
coroutineScope.launch(Dispatchers.Main.immediate) {
val thumb = async { imageLoader.get(thumbUrl) }
val fullSize = async { imageLoader.get(fullSizeUrl) }
fullSize.invokeOnCompletion { thumb.cancel() }
// There's probably a better way to do this.
val thumbDrawable = try {
thumb.await()
} catch (e: CancellationException) {
null
}
imageView.setDrawable(thumbDrawable)
val fullSizeDrawable = fullSize.await()
imageView.setDrawable(fullSizeDrawable)
}
Replace imageLoader
with Coil
if you use the singleton. To figure out whether or not to crossfade, you can add a Request.Listener
and check the returned DataSource
in onSuccess
.
Disclaimer: the above code is completely untested and unoptimized.
from coil.
I'd like something similar. I'd like to load image from cache (almost) immediately, but also check the network in the background for change.
Our image server supports ETag, and 304 Unchaged response. But because the URL is still the same, Coil will store the image in memory, and never asks the network again, so the user does not see the updated image. So I have the memory cache disabled, but then, when scrolling long list up and down, the images are always blank first and load later, which is distracting.
from coil.
Still waiting for this :(
from coil.
I would also like to see this feature implemented. I've created a library named AirBrush that uses this feature in Glide, but I'm planning to support Coil due to JetPack Compose. I can hack around it and use TransitionDrawable
but I would prefer to use the API :)
from coil.
This feature is the only thing keeping me using Glide for bigger projects. Would love to see a way to do that using Coil
from coil.
can anyone suggest any workaround for the coil to achieve the same?
from coil.
@0n4li Hey, thanks for improving that code 😊
from coil.
Is there any plan to support this feature?
This feature is the only thing keeping me using Glide for bigger projects. Would love to see a way to do that using Coil
same Here :'(
from coil.
any update on this ??
from coil.
val requestBuilder = Glide.with(context)
.asDrawable()
.sizeMultiplier(0.5f)
GlideImage(
model = contentUri,
contentDescription = null,
modifier = Modifier.fillMaxSize(),
contentScale = ContentScale.Crop,
){
it
.override(this.maxWidth.value.dpToPx(), this.maxHeight.value.dpToPx())
.thumbnail(requestBuilder)
}
does coil support thumbnail size loading as glide does? when i load lot of image in grid in compose, it seems to be delayed compared to scroll action while loading image.
from coil.
Any updates on this?
Interrested in the way to implement this behaviour with AsyncImage in compose)
from coil.
I tried this and it worked for me in compose:
AsyncImage(
model = "high resolution image",
placeholder = rememberAsyncImagePainter("low resolution image"),
contentScale = ContentScale.Crop,
contentDescription = "",
)
from coil.
Anyone have an idea on how to do this? Maybe we can throw up an MR to add this support.
from coil.
Related Issues (20)
- Image is flickering in compose horizontal view HOT 2
- Update NetworkObserver to call connectivityManager.registerDefaultNetworkCallback instead of connectivityManager.registerNetworkCallback HOT 3
- Coil3 alpha-08 not compatible with ktor 3.0-beta02 HOT 2
- Turn off network cache, clear app file will not be able to load images HOT 1
- Investigate SieveCache as coil memory cache for better performance HOT 6
- Why does Coil always refresh when loading different images with the same URL by default? Is it a bug? HOT 1
- Support fonts on SVG files HOT 1
- ImageBitmap Support for multiplatform HOT 2
- coil-network-ktor3 version: 3.0.0-alpha09 causes Ktor HttpClient to crash HOT 2
- Green overlay on images with AVIF format HOT 6
- [wasmJS] Build Error. HOT 1
- [Coil-3] SVG flickering while scrolling HOT 2
- Coil 3: Differing APIs make writing multiplatform code fiddly HOT 3
- Coil disk cache doesn't work when loading an icon file manually HOT 1
- Coil with web view for caching image HOT 1
- [Coil 3] Frequent `ImageDecoder$DecodeException: Input was incomplete.` when displaying an Uri from the Android PhotoPicker in Compose Multiplatform. HOT 8
- [Coil 3] Image Loading Silently Fails on Desktop HOT 4
- coil.request.NullRequestDataException: The request's data is null. HOT 1
- Web client fails due to CORS policy HOT 3
- listener and target not being executed when load animated images HOT 1
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from coil.