Decoder

April 25, 2026 · View on GitHub

翻译:English

Decoder 用于从 DataSource 读取数据并解码图像,Sketch 支持的每一种图片类型都有对应的 Decoder 为提供支持,如下表所示:

DecoderFormatDependent modulesAndroidiOSDesktopWeb
SkiaDecoderjpeg, png, webp, bmp-
BitmapFactoryDecoderjpeg, png, webp, bmp, heif (API 28), avif (API 31)-
[PhotosAssetDecoder]jpeg, png, webp, bmp, heif-
SkiaGifDecodergif (不支持 resize)sketch-animated-gif
MovieGifDecodergif (不支持 resize)sketch-animated-gif
ImageDecoderGifDecodergif (API 28)sketch-animated-gif
KoralGifDecodergifsketch-animated-gif-koral
ImageDecoderAnimatedWebpDecoderwebp 动图 (API 28)sketch-animated-webp
SkiaAnimatedWebpDecoderwebp 动图 (不支持 resize)sketch-animated-webp
ImageDecoderAnimatedHeifDecoderheif 动图 (API 30)sketch-animated-heif
SvgDecodersvg (非 Android 不支持 CSS)sketch-svg
VideoFrameDecoder视频帧sketch-video
FFmpegVideoFrameDecoder视频帧sketch-video-ffmpeg
[PhotosAssetVideoFrameDecoder]视频帧sketch-video
[FileVideoFrameDecoder]视频帧sketch-video
BlurHashDecoderBlurHashsketch-blurhash
ApkIconDecoderApk Iconsketch-extensions-core
DrawableDecoderAndoid res drawable-

每种 Decoder 的用途如下:

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

  1. 自定义 Decoder 需要应用 ImageRequest 中的很多与图片质量和尺寸相关的属性,例如 size、colorType、colorSpace 等,可参考其它 Decoder 实现
  2. 如果你的 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)
}