Jetpack Compose加载APNG

前言

APNG(Animated Portable Network Graphics,动画便携式网络图形)是一种基于 PNG(Portable Network Graphics)格式的扩展图像格式,用于支持逐帧动画,类似于 GIF,但具备更高的图像质量和更多功能。

APNG 是 GIF 的现代化替代方案,在保持良好兼容性的同时,提供了更丰富的色彩、真正的透明支持和更高效的压缩。

随着浏览器支持的普及,它在 Web 动画、表情包、轻量级 UI 动效等领域越来越受欢迎。

但是

Android本身不支持APNG,我们这里安装三方库(APNG4Android)来支持。

APNG4Android安装

https://github.com/penfeizhou/APNG4Android

安装依赖

1
2
//APNG支持
implementation("com.github.penfeizhou.android.animation:apng:3.0.5")

Compose封装

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
import android.widget.ImageView
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.viewinterop.AndroidView
import com.github.penfeizhou.animation.apng.APNGDrawable
import com.github.penfeizhou.animation.loader.AssetStreamLoader


@Composable
fun ZApngImage(
assetsApngPath: String,
modifier: Modifier = Modifier,
) {
val context = LocalContext.current

AndroidView(
factory = { ctx ->
val imageView = ImageView(ctx)
val assetLoader = AssetStreamLoader(context, assetsApngPath)
val apngDrawable = APNGDrawable(assetLoader)
imageView.setImageDrawable(apngDrawable)
imageView
},
modifier = modifier,
)
}

准备图片

我这里把图片放在了app/src/main/assets/apng目录下。

原因

不要将APNG资源放置到drawable或者mipmap目录下! 在Android app release构建过程中, aapt工具会压缩修改APNG资源的帧信息, 会导致播放不正常. 因此请将APNG资源放置到工程内的raw或者assets目录内.

调用

1
2
3
4
5
6
7
Box(
Modifier
.width(800.dp)
.height(400.dp)
) {
ZApngImage("apng/vs_success.png")
}