facebook / fresco

An Android library for managing images and the memory they use.
https://frescolib.org/
MIT License
17.07k stars 3.75k forks source link

Downscaling / resizing not supported for animated GIFs / WebPs #1975

Open JinohK opened 6 years ago

JinohK commented 6 years ago

GIF and JPG are in recyclerview

I want to do fitXY but gif is small --> git

cap

recyclerview item layout

<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="wrap_content">
    <com.facebook.drawee.view.SimpleDraweeView
        android:id="@+id/image"
        android:layout_width="match_parent"
        android:layout_height="170dp"
        app:actualImageScaleType="fitXY"/>
</android.support.constraint.ConstraintLayout>

recyclerview adapter

@Override
    public void onBindViewHolder(GallaryAdapter.ViewHolder holder, int position) {
        final CharacterData data = characterData.get(position);
        if(data.getType() == CharacterData.TYPE_GIF){
            holder.imageView.setController(Fresco.newDraweeControllerBuilder()
                    .setUri(data.getUri())
                    .setAutoPlayAnimations(true)
                    .build());
        }else{
            holder.imageView.setImageURI(data.getUri());
        }
    }

Thank you for your help.

dmitry-voronkevich commented 6 years ago

Hi, @JinohK, thank you for reporting this issue. I was able to reproduce it in our showcase app. Looks like we don't support downsampling of gifs.

winnerliu commented 6 years ago

@dmitry-voronkevich Have any plans to fix it?

oprisnik commented 6 years ago

Downsampling / resizing for GIFs is indeed not supported. Pull requests are welcomed :)

s1rius commented 6 years ago

@oprisnik I want to implement the "resizing for Webp" feature, Could you give us some idea or suggestions.

oprisnik commented 6 years ago

I'm assuming you mean animated WebPs and not static ones @s1rius.

The simplest way to get this to work is to adapt WebPImage. It implements the AnimatedImage interface, which holds image dimensions, frame metadata and AnimatedImageFrames. Instead of returning values for the original image, you'd have to return values for the resized image. AnimatedImageFrame (or more specifically WebPFrame in this case) is then used to draw frames to a bitmap, which you'd have to adapt to draw a resized version instead. This operation (as most of the other ones) is done in native code, see webp.cpp

It might be easier and more performant to downsample the image instead of performing actual resizing since you don't need to recompute all pixels.

Some background information on how this ties into the system: Currently, animated images are backed by BitmapAnimationBackend, which internally uses a BitmapFrameRenderer to render specific frames. Since multiple frames can overlap but we need to render the full frame, the AnimatedImageCompositor composes such a full frame. It looks at all partial frames that are required for the current animation time and assembles the final bitmap to be rendered. In order to do this composition, the information for each frame and rendering is implemented by AnimatedImage, which has 2 implementations WebPImage and GifImage.

For passing down the resized dimension, you could utilize a custom decoder, see http://frescolib.org/docs/customizing-image-formats.html

s1rius commented 6 years ago

Thanks a lot, I will try.

wartstone commented 4 years ago

@s1rius Any further outcome?

s1rius commented 4 years ago

@zheng03 see https://github.com/facebook/fresco/commit/7479a6fe103101fdf1bada5d2ed3f28a27e5e2f0

lucian1024 commented 2 years ago

@s1rius It is not working for animated webp. The method doesRenderSupportScaling in WebPImage return true so that it does not go into renderImageDoesNotSupportScaling in AnimatedDrawableBackendImpl. Maybe the method doesRenderSupportScaling in WebPImage should return false?