Android:如何使用android的ImageDecoder迭代webp帧

问题描述 投票:0回答:2

我想将动画 webp 转换为 gif,我有 gif 编码器+解码器和 webp ecnoder,它仅适用于 gif。我也想处理动画 webp,所以我需要首先解码动画 webp 并获取每个帧的位图。我无法获得任何动画 webp 解码器,后来发现 android.graphic 有支持动画 webp 图像的图像解码器,但它显示了可绘制的示例,并且它具有动画 webp 的 start() 方法。

如何迭代每个帧以将它们转换为位图或某些数据类型(如 byte[]、base64、流等),以便我可以将其转换为位图。

 File file = new File(...);
  ImageDecoder.Source source = ImageDecoder.createSource(file);
  Drawable drawable = ImageDecoder.decodeDrawable(source);
java android kotlin webp android-graphics
2个回答
1
投票

以下是我们如何在不使用任何第三方库的情况下从动画 webp 文件中提取帧。 根据 Google 的 WebP 图像格式容器规范, 我们需要以特定的方式阅读图像,您几乎可以使用任何您喜欢的语言来做到这一点。 在Java中,您可以创建动画webp文件的InputStream并按顺序读取4个字节的数据。 有一个库 android-webp-encoder 用于编码 webp 图像并用纯 java 编写。 尽管您也可以使用它来解码图像。需要修改库。我已修改但尚未发布。很快我会在修复 bug 的同时将其上传到 github 上。

但是我可以解释如何修改该库来解码帧或编写自己的代码来解码。

  1. 首先创建图像的输入流
  2. 以 4 字节块读取数据,直到文件末尾。 正在阅读:
  3. 读取4个字节并检查是否是'RIFF'字符。
  4. 然后读取接下来的 4 个字节。这是文件大小。
  5. 文件大小之后的接下来 4 个字节必须是“WEBP”字符
  6. 接下来的 4 个字节将给出“VP8X”字符。我们实际的图像数据和参数从这里开始。
  7. 接下来的 4 个字节必须包含值 10,因为之后我们需要以 google 容器规范中规定的特定方式读取 10 个字节。
  8. 在 VP8X、ANIM 和其他可选块之后,我们必须读取 ANMF,然后是 ALPH(可选)数据、VP8/VP8L 数据。这些是我们需要提取并创建位图的实际图像数据。
  9. 每个 ANMF 的出现都会向我们发出有关每个帧的信号。
  10. 您可以将静态webp图像数据写入ByteArrayOutputStream并创建 使用 BitmapFactory.decodeByteArray(stream) 的位图。这将返回该帧的位图图像。

PS:我将用更详细的步骤和代码片段更新答案。目前我正在尝试优化解码器


0
投票

作为实现相同目标的替代方案,我通过使用 Glide 和 APNG4 库以及 git 上提供的一些编码器解码器解决了这个问题。

您可以使用 APNG4 单独进行编码解码和其他操作。

https://github.com/penfeizhou/APNG4Android

© www.soinside.com 2019 - 2024. All rights reserved.