Decoder
April 25, 2026 · View on GitHub
翻译:English
Decoder 用于从 DataSource 读取数据并解码图像,Sketch 支持的每一种图片类型都有对应的 Decoder 为提供支持,如下表所示:
| Decoder | Format | Dependent modules | Android | iOS | Desktop | Web |
|---|---|---|---|---|---|---|
| SkiaDecoder | jpeg, png, webp, bmp | - | ❌ | ✅ | ✅ | ✅ |
| BitmapFactoryDecoder | jpeg, png, webp, bmp, heif (API 28), avif (API 31) | - | ✅ | ❌ | ❌ | ❌ |
| [PhotosAssetDecoder] | jpeg, png, webp, bmp, heif | - | ❌ | ✅ | ❌ | ❌ |
| SkiaGifDecoder | gif (不支持 resize) | sketch-animated-gif | ❌ | ✅ | ✅ | ✅ |
| MovieGifDecoder | gif (不支持 resize) | sketch-animated-gif | ✅ | ❌ | ❌ | ❌ |
| ImageDecoderGifDecoder | gif (API 28) | sketch-animated-gif | ✅ | ❌ | ❌ | ❌ |
| KoralGifDecoder | gif | sketch-animated-gif-koral | ✅ | ❌ | ❌ | ❌ |
| ImageDecoderAnimatedWebpDecoder | webp 动图 (API 28) | sketch-animated-webp | ✅ | ❌ | ❌ | ❌ |
| SkiaAnimatedWebpDecoder | webp 动图 (不支持 resize) | sketch-animated-webp | ❌ | ✅ | ✅ | ✅ |
| ImageDecoderAnimatedHeifDecoder | heif 动图 (API 30) | sketch-animated-heif | ✅ | ❌ | ❌ | ❌ |
| SvgDecoder | svg (非 Android 不支持 CSS) | sketch-svg | ✅ | ✅ | ✅ | ✅ |
| VideoFrameDecoder | 视频帧 | sketch-video | ✅ | ❌ | ❌ | ❌ |
| FFmpegVideoFrameDecoder | 视频帧 | sketch-video-ffmpeg | ✅ | ❌ | ❌ | ❌ |
| [PhotosAssetVideoFrameDecoder] | 视频帧 | sketch-video | ❌ | ✅ | ❌ | ❌ |
| [FileVideoFrameDecoder] | 视频帧 | sketch-video | ❌ | ✅ | ❌ | ❌ |
| BlurHashDecoder | BlurHash | sketch-blurhash | ✅ | ✅ | ✅ | ✅ |
| ApkIconDecoder | Apk Icon | sketch-extensions-core | ✅ | ❌ | ❌ | ❌ |
| DrawableDecoder | Andoid res drawable | - | ✅ | ❌ | ❌ | ❌ |
每种 Decoder 的用途如下:
- SkiaDecoder:在非 Android 平台上使用 Skia 内置的 Image 解码图片,它是非 Android 平台最后的解码器
- BitmapFactoryDecoder:在 Android 平台上使用 Android 内置的 BitmapFactory 解码图片,它是 Android 平台最后的解码器
- [PhotosAssetDecoder]:在 iOS 平台上解码来自 Photos Library 的图片
- SkiaGifDecoder:在非 Android 平台上使用 Skia 内置的 Codec 解码 gif 动图(了解更多)
- MovieGifDecoder:在 Android 平台上使用 Android 内置的 Movie 解码 gif 动图(了解更多)
- ImageDecoderGifDecoder:在 Android 平台上使用 Android 内置的 ImageDecoder 解码 gif 动图(了解更多)
- KoralGifDecoder:在 Android 平台上使用 koral-- 的 android-gif-drawable 库解码 gif 动图(了解更多)
- ImageDecoderAnimatedWebpDecoder:在 Android 平台上使用 Android 内置的 ImageDecoder 解码 webp 动图(了解更多)
- SkiaAnimatedWebpDecoder:在非 Android 平台上使用 Skia 内置的 Codec 解码 webp 动图(了解更多)
- ImageDecoderAnimatedHeifDecoder:使用 Android 内置的 ImageDecoder 解码 heif 动图(了解更多)
- SvgDecoder:在 Android 平台上使用 BigBadaboom 的 androidsvg 库,在非 Android 平台上使用 Skia 内置的 SVGDOM 解码静态 svg 文件(了解更多)
- VideoFrameDecoder:在 Android 平台上使用 Android 内置的 MediaMetadataRetriever 类解码视频文件的帧(了解更多)
- FFmpegVideoFrameDecoder:在 Android 平台上使用 wseemann 的 FFmpegMediaMetadataRetriever 库解码视频帧(了解更多)
- [PhotosAssetVideoFrameDecoder]:在 iOS 平台上解码来自 Photos Library 视频文件的帧
- [FileVideoFrameDecoder]:在 iOS 平台上解码来自本地视频文件的帧
- BlurHashDecoder:从 BlurHash 字符串解码模糊图像 (了解更多)
- ApkIconDecoder:在 Android 平台上解码 Apk 文件的图标(了解更多)
- DrawableDecoder:在 Android 平台上解码 vector、shape 等 Android 支持的 xml drawable 图片
Important
- 内置的不依赖额外模块的 Decoder 都已经注册了
- 依赖额外模块的 Decoder 也都支持自动注册,你只需要配置好依赖即可
- 如果你需要手动注册,请阅读文档:《注册组件》
解码静态图片
Android 平台
在 Android 平台上主要使用 BitmapFactoryDecoder 解码静态图片,BitmapFactoryDecoder 使用 Android 内置的 BitmapFactory 解码图片,支持的图片格式和最低版本请参考上表。
桌面和 Web 平台
在桌面和 Web 平台上主要使用 SkiaDecoder 解码静态图片,SkiaDecoder 使用 Skia 内置的 Image 解码图片,支持的图片格式请参考上表。
iOS 平台
ios 平台上同样主要使用 SkiaDecoder 解码静态图片,但对于来自 Photos Library 的图片会优先使用 [PhotosAssetDecoder] 解码,[PhotosAssetDecoder] 使用 ios 原生的 PHImageManager 解码图片,这样能够利用系统自身的能力支持更多的图片格式。
如果你想使用 SkiaDecoder 解码来自 Photos Library 的图片可以通过 useSkiaForImagePhotosAsset()
函数实现,如下:
val imageUri = newPhotosAssetUri("DB16113B-984A-4D12-B4D0-50FC46066781/L0/001")
val request = ImageRequest(context, imageUri) {
useSkiaForImagePhotosAsset(true)
}
AsyncImage(
request = request,
contentDescription = "photo"
)
UseSkiaInterceptor 在检测到 useSkiaForImagePhotosAsset 为 true 后就会在 fetch 之后将图片原始数据全部读到内存中再包装成 ByteArrayDataSource 供 SkiaDecoder 解码
如果你还想将来自 Photos Library 的图片原始数据缓存到下载缓存中再包装成 FileDataSource
供 SkiaDecoder 解码,可以通过 preferFileCacheForImagePhotosAsset() 函数实现,如下:
val imageUri = newPhotosAssetUri("DB16113B-984A-4D12-B4D0-50FC46066781/L0/001")
val request = ImageRequest(context, imageUri) {
useSkiaForImagePhotosAsset(true)
preferFileCacheForImagePhotosAsset(true)
}
AsyncImage(
request = request,
contentDescription = "photo"
)
解码动图
解码动图请参考文档:《动图》
解码 SVG
解码 SVG 请参考文档:《SVG》
解码视频帧
解码视频帧请参考文档:《视频帧》
解码 BlurHash
解码 BlurHash 请参考文档:《BlurHash》
解码 APK 图标
解码 APK 图标请参考文档:《加载 Apk 图标》
解码 Android Drawable
在 Android 平台主要使用 DrawableDecoder 解码 vector、shape 等 Android 支持的 xml drawable 图片,它的原理就是将 Drawable 绘制到 Bitmap 上,因此要求 Drawable 必须有固有尺寸。
自定义 Decoder
先实现 Decoder 接口定义你的 Decoder 和它的 Factory
注意 Decoder.sortWeight 属性的值,他决定当前 Decoder 在 Decoder 列表中的位置,值越大在列表中越靠后。取值范围是 0 ~ 100
然后参考文档 《注册组件》 注册你的 Decoder 即可
Caution
- 自定义 Decoder 需要应用 ImageRequest 中的很多与图片质量和尺寸相关的属性,例如 size、colorType、colorSpace 等,可参考其它 Decoder 实现
- 如果你的 Decoder 是解码动图的话一定要判断 ImageRequest.disallowAnimatedImage 参数
解码属性
BitmapColorType
BitmapColorType 用于设置位图的颜色类型,可选值有:
- FixedColorType:始终使用指定的颜色类型
- LowQualityColorType:优先使用低质量的颜色类型
- Android 平台上 jpeg 图片使用 RGB_565,其它使用默认值
- 非 Android 平台上 jpeg 和 webp 图片使用 RGB_565,其它使用 ARGB_4444
- HighQualityColorType:优先使用高质量的颜色类型
- Android 平台上 API 26 以上使用 RGBA_F16,其它使用默认值
- 非 Android 平台上始终使用 RGBA_F16
示例:
ImageRequest(context, "https://example.com/image.jpg") {
// 在 Android 平台上使用指定的颜色类型
colorType(Bitmap.Config.RGB_565)
// 在非 Android 平台上使用指定的颜色类型
colorType(ColorType.RGBA_F16)
// 优先使用低质量的颜色类型
colorType(LowQualityColorType)
// 优先使用高质量的颜色类型
colorType(HighQualityColorType)
}
BitmapColorSpace
BitmapColorSpace 用于设置位图的颜色空间,可选值有:
- FixedColorSpace:始终使用指定的颜色空间
示例:
ImageRequest(context, "https://example.com/image.jpg") {
// 在 Android 平台上使用指定的颜色空间
colorSpace(ColorSpace.Named.DISPLAY_P3)
// 在非 Android 平台上使用指定的颜色空间
colorSpace(ColorSpace.displayP3)
}
preferQualityOverSpeed
preferQualityOverSpeed 用于设置质量优先解码时质量优先,只能在 Android 平台使用。
示例:
ImageRequest(context, "https://example.com/image.jpg") {
preferQualityOverSpeed(true)
}