Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Glide Webp support with compose integration #4943

Closed
abdulelahragih opened this issue Nov 3, 2022 · 5 comments
Closed

Glide Webp support with compose integration #4943

abdulelahragih opened this issue Nov 3, 2022 · 5 comments

Comments

@abdulelahragih
Copy link

Glide Version:
4.14.2

Integration libraries:
com.github.bumptech.glide:compose:1.0.0-alpha.1

Device/Android Version:
API 31

Issue details / Repro steps / Use case background:
I am trying to load an animated webp image from a URL. With XML views system, it works but when I tried it with the compose it fails with an exception as you can see below

As I know, Glide does support webp. So do I have to do something or add any code?
The compose integration is fairly new so I could not find something related on the docs or the web.

Moreover, I tried using AndroidView composable as follow and it worked. So this confirm that the underlying system can decode webp.

AndroidView(factory = { context ->
       ImageView(context).apply {
           scaleType = ImageView.ScaleType.CENTER_CROP
           Glide.with(context)
               .load(
                   "https://img-04.stickers.cloud/packs/33eecb0b-3b89-4bdf-be6f-dd7900b19dd3/webp/animated/b0887107-f7cc-424a-bbe8-7b3d6cb23b69.webp"
               ).into(this)
        }
    })

Glide load line / GlideModule (if any) / list Adapter code (if any):

// Put it in a wrapper so I can easily change to any Image loader
@OptIn(ExperimentalGlideComposeApi::class)
@Composable
fun NetworkImage(
    url: String?,
    contentDescription: String?,
    modifier: Modifier = Modifier,
    alignment: Alignment = Alignment.Center,
    contentScale: ContentScale = ContentScale.Fit,
    alpha: Float = DefaultAlpha,
    colorFilter: ColorFilter? = null
) {
    GlideImage(
        model = url,
        contentDescription = contentDescription,
        contentScale = contentScale,
        modifier = modifier,
        alignment = alignment,
        alpha = alpha,
        colorFilter = colorFilter
    )
}

// then I use it like this inside a my layout
    NetworkImage(
        modifier = Modifier
            .clip(RoundedCornerShape(16.dp))
            .size(size)
            .background(color = MaterialTheme.colors.onSurface.copy(alpha = 0.5f)),
        url = webpUrl,
        contentDescription = null,
        contentScale = ContentScale.Crop
    )

Stack trace / LogCat:

Load failed for [https://img-04.stickers.cloud/packs/33eecb0b-3b89-4bdf-be6f-dd7900b19dd3/webp/animated/b0887107-f7cc-424a-bbe8-7b3d6cb23b69.webp] with dimensions [243x243]
class com.bumptech.glide.load.engine.GlideException: Failed to load resource
There was 1 root cause:
java.lang.IllegalArgumentException(Unable to convert android.graphics.drawable.AnimatedImageDrawable@235bcbf to a Bitmap)
call GlideException#logRootCauses(String) for more detail
Cause (1 of 1): class java.lang.IllegalArgumentException: Unable to convert android.graphics.drawable.AnimatedImageDrawable@235bcbf to a Bitmap
2022-11-03 23:47:36.617  8562-8607  Glide         app.arabstickers        I  Root cause (1 of 1)
java.lang.IllegalArgumentException: Unable to convert android.graphics.drawable.AnimatedImageDrawable@235bcbf to a Bitmap
at com.bumptech.glide.load.resource.bitmap.DrawableTransformation.transform(DrawableTransformation.java:55)
at com.bumptech.glide.load.engine.DecodeJob.onResourceDecoded(DecodeJob.java:578)
at com.bumptech.glide.load.engine.DecodeJob$DecodeCallback.onResourceDecoded(DecodeJob.java:642)
at com.bumptech.glide.load.engine.DecodePath.decode(DecodePath.java:60)
at com.bumptech.glide.load.engine.LoadPath.loadWithExceptionList(LoadPath.java:76)
at com.bumptech.glide.load.engine.LoadPath.load(LoadPath.java:57)
at com.bumptech.glide.load.engine.DecodeJob.runLoadPath(DecodeJob.java:539)
at com.bumptech.glide.load.engine.DecodeJob.decodeFromFetcher(DecodeJob.java:503)
at com.bumptech.glide.load.engine.DecodeJob.decodeFromData(DecodeJob.java:489)
at com.bumptech.glide.load.engine.DecodeJob.decodeFromRetrievedData(DecodeJob.java:434)
at com.bumptech.glide.load.engine.DecodeJob.onDataFetcherReady(DecodeJob.java:399)
at com.bumptech.glide.load.engine.DataCacheGenerator.onDataReady(DataCacheGenerator.java:100)
at com.bumptech.glide.load.model.ByteBufferFileLoader$ByteBufferFetcher.loadData(ByteBufferFileLoader.java:62)
at com.bumptech.glide.load.engine.DataCacheGenerator.startNext(DataCacheGenerator.java:77)
at com.bumptech.glide.load.engine.DecodeJob.runGenerators(DecodeJob.java:311)
at com.bumptech.glide.load.engine.DecodeJob.runWrapped(DecodeJob.java:277)
at com.bumptech.glide.load.engine.DecodeJob.run(DecodeJob.java:235)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
at com.bumptech.glide.load.engine.executor.GlideExecutor$DefaultThreadFactory$1.run(GlideExecutor.java:421)
at java.lang.Thread.run(Thread.java:920)
at com.bumptech.glide.load.engine.executor.GlideExecutor$DefaultPriorityThreadFactory$1.run(GlideExecutor.java:380)
@Yahyalutf
Copy link

I'm having the same problem !! did you find a solution to your problem ?

@abdulelahragih
Copy link
Author

I'm having the same problem !! did you find a solution to your problem?

Still experimenting but no fix. As a workaround, I am using the AndroidView as I demonstrated in the issue above.

@sjudd
Copy link
Collaborator

sjudd commented Nov 7, 2022

This appears to be due to:

centerCrop()
}
ContentScale.Inside,
ContentScale.Fit -> {
// Outside compose, glide would use fitCenter() for FIT. But that's probably not a good
// decision given how unimportant Bitmap re-use is relative to minimizing texture sizes now.
// So instead we'll do something different and prefer not to upscale, which means using
// centerInside(). The UI can still scale the view even if the Bitmap is smaller.
centerInside()

In particular we're using centerCrop() and centerInside() which throw if they cannot be applied to the loaded resource. We should instead use the optional equivalents that are ignored if they can't be applied to match the behavior of RequestBuilder:

requestOptions = requestOptions.clone().optionalCenterCrop();
break;
case CENTER_INSIDE:
requestOptions = requestOptions.clone().optionalCenterInside();
break;
case FIT_CENTER:
case FIT_START:
case FIT_END:
requestOptions = requestOptions.clone().optionalFitCenter();
break;
case FIT_XY:
requestOptions = requestOptions.clone().optionalCenterInside();

@sjudd
Copy link
Collaborator

sjudd commented Nov 7, 2022

Oh I should mention a simple workaround until this is fixed is to specify a transformation (or dontTransform()) using requestBuilderTransform:

GlideImage(...) { it -> it.optionalFitCenter() } 

You can replace optionalFitCenter() with whatever transformation is appropriate for your ContentScale value, so long as you use the optional variant.

@abdulelahragih
Copy link
Author

Oh I should mention a simple workaround until this is fixed is to specify a transformation (or dontTransform()) using requestBuilderTransform:

GlideImage(...) { it -> it.optionalFitCenter() } 

You can replace optionalFitCenter() with whatever transformation is appropriate for your ContentScale value, so long as you use the optional variant.

Hi Sam,
Thank you so much for your reply and help.
The workaround works perfectly.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants