0

I wanna get the gif through DataSubscriber by Fresco.But when i get the CloseableAnimatedImage, I don't know how to get the bitmap of it.

 public void getBitmap(String url, final OnBitmapFetchedListener listener) {
            ImageRequest request = ImageRequest.fromUri(Uri.parse(url));

        final ImagePipeline imagePipeline = Fresco.getImagePipeline();
        DataSource<CloseableReference<CloseableImage>>
                dataSource = imagePipeline.fetchDecodedImage(request, null);

        DataSubscriber dataSubscriber = new BaseDataSubscriber<CloseableReference<CloseableImage>>() {

            @Override
            protected void onNewResultImpl(DataSource<CloseableReference<CloseableImage>> closeableReferenceDataSource) {

                CloseableReference<CloseableImage> imageReference = closeableReferenceDataSource.getResult();
                if (imageReference != null) {
                    try {
                        CloseableImage image = imageReference.clone().get();
                        if (image instanceof CloseableAnimatedImage) {
                            //here i get the gif but i don't know how to get the bitmap
                        }    
                    }
                }
            }

and i tried another way to get the bitmap of a pic:

fun getBitmap(uri: Uri, listener: OnBitmapFetchedListener) {
val request = ImageRequest.fromUri(uri)

val imagePipeline = Fresco.getImagePipeline()
val dataSource = imagePipeline.fetchEncodedImage(request, null)

val dataSubscriber = object : BaseDataSubscriber<CloseableReference<PooledByteBuffer>>() {

    override fun onNewResultImpl(closeableReferenceDataSource: DataSource<CloseableReference<PooledByteBuffer>>) {

        val imageReference = closeableReferenceDataSource.result
        if (imageReference != null) {
            try {
                val image = imageReference.clone().get()

                val inputStream = PooledByteBufferInputStream(image)

                val imageFormat = ImageFormatChecker.getImageFormat(inputStream)

                Log.e("ImageUtil", "imageFormat = ${ImageFormat.getFileExtension(imageFormat)}")
                val bitmap = BitmapFactory.decodeStream(inputStream)

                listener.onSuccess(bitmap)

            } catch (e: IOException) {
                Log.e("ImageUtil", "error:$e")
            } finally {
                imageReference.close()
            }
        }
    }

    override fun onFailureImpl(closeableReferenceDataSource: DataSource<CloseableReference<PooledByteBuffer>>) {
        Log.e("ImageUtil", "fail")

        listener.onFail()
    }
}

It's kotlin code, what i do is using fetchEncodedImage and get the inputStream of a pic. But it always go onFailImpl(), I don't know why.

Allen Vork
  • 1,536
  • 3
  • 16
  • 29

1 Answers1

1

It seems that the real question is how to statically display only the first frame of an animated image. This is not supported at the moment, but it would be very easy to implement.

Fresco already has ImageDecodeOptions object. You would just need to add another field there: public final boolean decodeAsStaticImage. Then in ImageDecoder.decodeGif you just need to change:

if (GifFormatChecker.isAnimated(is)) {
  return mAnimatedImageFactory.decodeGif(...);
}
return decodeStaticImage(encodedImage);

to:

if (!options.decodeAsStaticImage && GifFormatChecker.isAnimated(is)) {
  return mAnimatedImageFactory.decodeGif(...);
}
return decodeStaticImage(encodedImage);

Please feel free to implement this and make a pull request to our GitHub Fresco repository.

And then in the client code, you just need to set your decode options to the image request with ImageRequestBuilder.setImageDecodeOptions.

plamenko
  • 1,068
  • 1
  • 8
  • 10