Android : How to iterate through webp frames using android's ImageDecoder

915 Views Asked by At

I want to convert the animated webp into gif and I have gif encoder+decoder and webp ecnoder and it is working fine with gifs only. I want to process the animated webp as well so I need to decode the animated webp first and get bitamps for each frames. I could not get any animated webp decoder and later found that android.graphic has Image decoder which support animated webp image but it shown example for drawable and it has start() method for animated webp.

How can I iterate through each frames to convert them into bitmap or some data type like byte[], base64, streams, etc so that i can convet that into bitmap.

 File file = new File(...);
  ImageDecoder.Source source = ImageDecoder.createSource(file);
  Drawable drawable = ImageDecoder.decodeDrawable(source);
2

There are 2 best solutions below

0
On BEST ANSWER

Here is how we can extract frames from animated webp file without using any third party library. According to Google's Container Specification for WebP image format, We need to read the image in specific way and you can do that with almost any language you like. In Java you can create InputStream of animated webp file and read data in 4 bytes in sequence. There is library android-webp-encoder for encoding webp image and written in pure java. Although you can use it for decoding the image as well. Need to modify the the library. I have modified it but not published yet. Soon I will upload it on github as I fix the bugs.

But I can explain how to modify that library to decode frames or write your own codes to decode.

  1. First create inputstream of image
  2. Read data in 4 bytes chunks till the end of file. Reading:
  3. Read 4 bytes and check if it is 'RIFF' characters.
  4. Then read next 4 bytes. This is file size.
  5. After file size next 4 bytes must be 'WEBP' characters
  6. Next 4 bytes will give 'VP8X' characters. Our actual image data and parameters starts from here.
  7. Next 4 bytes must should contain value 10 as after that we need to read 10 bytes in specific manner stated in the google's container specification.
  8. After VP8X, ANIM and other optional chunks we have to read ANMF followed by ALPH (optional) data, VP8/VP8L data. these are the actual image data we need to extract and create bitmaps out of it.
  9. Each ANMF occurrence will signal us about each frames.
  10. You can write static webp image data to ByteArrayOutputStream and create bitmap using BitmapFactory.decodeByteArray(stream). This will return bitmap image of that frame.

PS: I will update the answer with more detailed steps and code snippets. Currently I am trying to optimise the decoder

0
On

As alternative for achieving same goal I have solved this by using Glide and APNG4 library along with some encoder decoder available on git.

You can do both encode decode and and other stuff alone with APNG4.

https://github.com/penfeizhou/APNG4Android