Webp容器规范

Webp容器规范

简介

WebP 是一种图片格式,它使用 (i) VP8 关键帧编码以有损方式压缩图片数据,或 (ii) 使用 WebP 无损编码(将来也可能会使用其他 Web 编码)。这些编码方案应该比当前使用的格式更高效。它经过优化,可通过网络快速传输图片(例如,针对网站)。WebP 格式也具有与其他格式相同的特征(颜色配置文件、元数据、动画等)。本文档介绍了 WebP 文件的结构。

WebP 容器(即支持 WebP 的 RIFF 容器支持对 WebP 基本用例(即包含编码为 VP8 关键帧的单张图片的文件)提供的功能支持。WebP 容器为以下各项提供了额外的支持:

  • 无损压缩:图片可以使用 WebP 无损格式进行无损压缩。
  • 元数据。图片可能包含以 Exif 或 XMP 格式存储的元数据。
  • 透明度。图像可以有透明度,即 Alpha 通道。
  • 颜色配置文件:如国际颜色联盟所述,图片可能具有嵌入式 ICC 配置文件。
  • 动画:一张图片可能具有多个帧,并且这些帧之间出现暂停,使其成为动画。

关键词“必须”“不得”“必需”“应”“不应”“应简短说明”

块图中的位编号从 0 开始,对于最高有效位 (‘MSB 0’),如 RFC 1166 中所述。

命名

建议在引用 WebP 容器时使用以下类型:

容器格式名称WebP
文件扩展名.webp
MIME 类型图片/WebP
统一类型标识符org.webmproject.webp

WebP 文件格式基于 RIFF(资源交换文件格式)文档格式。

术语与基础知识

WebP 文件包含静态图片(即编码后的像素矩阵)或动画。您还可以选择包含透明度信息、颜色配置文件和元数据。如果我们只需要引用像素矩阵,我们将它称为图像的画布。

以下是本文档中使用的其他术语:

读者/作者

读取 WebP 文件的代码称为“读取器”,而写入它们的代码称为“写入者”。

uint16

一个 16 位、小端字节序且无符号整数。

uint24

24 位、小端字节序且无符号整数。

uint32

一个 32 位、小端字节序且无符号整数。

FCC

FourCC(四个字符的代码)是一个uint32,通过以小端顺序连接四个 ASCII 字符创建。
这意味着 &a39;aaaa' (0x61616161) 和 &AA39;AAAA' (0x41414141) 被视为不同的 FourCC。

基于 1

一个无符号整数字段,用于存储由 -1 偏移的值。例如此类字段会将值 25 存储为 24。

ChunkHeader ‘ABCD’)

这用于描述各个分块的 FourCC 和 Chunk Size 头文件,其中“ABCD”是分块的 FourCC。
此元素的大小为 8 个字节。

RIFF 文件格式

WebP 文件格式基于 RIFF(资源交换文件格式)文档格式。
RIFF 文件的基本元素是块。其中包括:

 0                   1                   2                   3
 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                         Chunk FourCC                          |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                          Chunk Size                           |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
:                         Chunk Payload                         :
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

数据块 FourCC:32 位

用于识别分块的 ASCII 四字符代码。

分块大小:32 位 (uint32)

以字节为单位的分块的大小,不包括此字段、分块标识符或内边距。

分块载荷:分块大小字节

数据载荷。如果分块大小为奇数,则会添加单个填充字节(必须为 0 以符合 RIFF 标准)。

注意:RIFF 的惯例是,所有大写 FourCC 都是适用于任何 RIFF 文件格式的标准区块,而特定于文件格式的 FourCC 全部小写。WebP 不遵循此惯例。

WebP 文件标头

 0                   1                   2                   3
 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|      'R'      |      'I'      |      'F'      |      'F'      |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                           File Size                           |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|      'W'      |      'E'      |      'B'      |      'P'      |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

‘RIFF’:32 位

ASCII 字符 ('R'I' I' 'F' 'F')。

文件大小:32 位 (uint32)

从偏移量 8 开始的文件的大小(以字节为单位)。
此字段的最大值为 2^32 减去 10 个字节,因此整个文件的大小最多为 4GiB 减去 2 个字节。

‘WEBP’:32 位

ASCII 字符 (W'E'E' 'B' 'P')。

WebP 文件必须以 FourCC ‘WEBP’ 开头的 RIFF 标头开头。标头中的文件大小是指数据块后面的数据块大小加上 4 字节的 ‘WEBP’ FourCC。此文件不应包含文件大小所指定的数据后面的任何数据。读者可以解析此类文件,并忽略尾随数据。由于任何分块的大小都是偶数,因此 RIFF 标头给出的大小也是偶数。下面几部分将介绍各个分块的内容。

简单的文件格式(有损)

如果图片需要有损编码,并且不需要透明度或使用扩展格式提供的其他高级功能,则应使用此布局。采用这种布局的文件较小并且受旧版软件支持。

简单的 WebP(有损)文件格式:

 0                   1                   2                   3
 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                                                               |
|                    WebP file header (12 bytes)                |
|                                                               |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
:                          VP8 chunk                            :
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

VP8 分块:

 0                   1                   2                   3
 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                      ChunkHeader('VP8 ')                      |
|                                                               |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
:                           VP8 data                            :
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

VP8 数据:数据块大小字节

VP8 比特流数据。

注意 'VP8 ’ FourCC 是一个 ASCII 空格 (0x20)。

如需了解 VP8 比特流格式规范,请参阅 VP8 数据格式和解码指南。请注意,VP8 帧标头包含 VP8 帧宽度和高度。假定画布的宽度和高度为该值。

VP8 规范说明了如何将图片解码为 Y’CbCr 格式。如需转换为 RGB,应使用 Rec. 601。应用可以使用其他转换方法,但解码器的视觉结果可能有所不同。

简单的文件格式(无损)

注意:旧版阅读器可能不支持使用无损格式的文件。

如果图片需要无损编码(具有可选的透明度通道),并且不需要扩展格式提供的高级功能,则应使用此布局。

简单的 WebP(无损)文件格式:

 0                   1                   2                   3
 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                                                               |
|                    WebP file header (12 bytes)                |
|                                                               |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
:                          VP8L chunk                           :
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

VP8L 分块:

 0                   1                   2                   3
 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                      ChunkHeader('VP8L')                      |
|                                                               |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
:                           VP8L data                           :
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

VP8L 数据:数据块大小字节

VP8L 比特流数据。

如需了解 VP8L 比特流的当前规范,请参阅 WebP 无损比特流格式。请注意,VP8L 头文件包含 VP8L 图像宽度和高度。假设该值是画布的宽度和高度。

扩展文件格式

注意:旧版阅读器可能不支持采用扩展格式的文件。

扩展格式文件由以下部分组成:

  • 一个块,包含文件所用功能的相关信息。
  • 具有颜色配置文件的可选 'ICCP& 数据块。
  • (可选)包含动画控制数据的分块。
  • 图片数据。
  • 包含 Exif 元数据的可选 &EX3’ 分块。
  • 包含 XMP 元数据的可选 &X39;XMP 代码块。
  • 可选的未知分块列表。

对于静态图片,图片数据由单个帧组成,该帧由以下部分组成:

  • 可选的 Alpha 子区块。
  • 比特流子区块。

对于动画图片,图片数据由多个帧组成。如需详细了解帧,请参阅动画部分。

所有区块应按上述顺序排列。如果某个分块出现在错误的位置,则表示文件无效,但读者可以解析该文件,并忽略乱序的分块。

说明:设置分块的顺序应该能够更快地解析文件。例如,如果 ‘ALPH’ 分块未显示在所需的位置,解码器可以选择停止搜索它。忽略后期数据块的规则应该使需要执行完整搜索的程序获得与提前停止的程序相同的结果。

扩展的 WebP 文件标头:

 0                   1                   2                   3
 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                                                               |
|                   WebP file header (12 bytes)                 |
|                                                               |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                      ChunkHeader('VP8X')                      |
|                                                               |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|Rsv|I|L|E|X|A|R|                   Reserved                    |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|          Canvas Width Minus One               |             ...
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
...  Canvas Height Minus One    |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

保留 (Rsv):2 位

必须为 0。读者必须忽略此字段。

ICC 配置文件 (I):1 位

如果文件包含 ICC 配置文件,则设置此参数。

Alpha (L):1 位

如果图片的任何帧包含透明度信息 ("alpha"),请设置此参数。

Exif 元数据 (E):1 位

如果文件包含 Exif 元数据,则设置此参数。

XMP 元数据 (X):1 位

如果文件包含 XMP 元数据,则设置此参数。

动画 (A):1 位

如果这是动画图片,请设置。ANIMF 和 ANMF' 分块中的数据应使用块来控制动画。

保留 ®:1 位

必须为 0。读者必须忽略此字段。

预留:24 位

必须为 0。读者必须忽略此字段。

画布宽度减去一:24 位

画布的基于 1 的宽度(以像素为单位)。 实际的画布宽度为 1 + Canvas Width Minus One。

画布高度减去一:24 位

画布的基于 1 的高度(以像素为单位)。 实际画布高度为 1 + Canvas Height Minus One。
画布宽度和画布高度的乘积不得超过 2^32 - 1。
将来的规范可能会添加更多字段。必须忽略未知字段。

动画

动画由 ANIM 和 ANMF 分块控制。

ANIM 数据块:

对于动画图片,此块包含动画的全局参数。

 0                   1                   2                   3
 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                      ChunkHeader('ANIM')                      |
|                                                               |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                       Background Color                        |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|          Loop Count           |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

背景颜色:32 位 (uint32)

画布的默认背景颜色,按 [蓝色、绿色、红色、Alpha 版] 字节顺序排列。
此颜色可用于填充画布四周未使用的画布空间,以及第一帧的透明像素。
处置方法为 1 时,也会使用背景颜色。

注意:

  • 即使 VP8X 分块中的 Alpha 标志未设置,背景颜色也可包含非不透明 Alpha 值。
  • 查看者应用应将背景颜色值视为提示,并非必须使用。
  • 在每次循环开始时,系统都会清空画布。为此,可以使用背景颜色。

循环计数:16 位 (uint16)

动画的循环次数。0 表示无限。

如果设置了 VP8X 分块中的 Animation 标记,则必须显示相应分块。 如果未设置 Animation 标记且存在此分块,则必须忽略该分块。

ANMF 分块:

对于动画图片,此块包含有关单个帧的信息。如果未设置动画标志,则此块不应存在。

 0                   1                   2                   3
 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                      ChunkHeader('ANMF')                      |
|                                                               |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                        Frame X                |             ...
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
...          Frame Y            |   Frame Width Minus One     ...
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
...             |           Frame Height Minus One              |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                 Frame Duration                |  Reserved |B|D|
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
:                         Frame Data                            :
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

帧 X:24 位 (uint24)

框架左上角的 X 坐标为 Frame X * 2。

帧 Y:24 位 (uint24)

框架左上角的 Y 坐标为 Frame Y * 2。

帧宽 - 减 1:24 位 (uint24)

帧的从 1 开始的宽度。帧宽度为 1 + Frame Width Minus One。

帧高度减去一:24 位 (uint24)

帧的从 1 开始的高度。 帧高度为 1 + Frame Height Minus One。

帧时长:24 位 (uint24)

显示下一帧前的等待时间,以 1 毫秒为单位。请注意,帧时长 0(通常 <= 10)解释为实现定义。
许多工具和浏览器都会指定类似于 GIF 的最短时长。

预留:6 位

必须为 0。读者必须忽略此字段。

混合方法 (B):1 位
指示当前帧的透明像素如何与上一画布的相应像素混合:

  • 0:使用 alpha 混合。处理上一个帧后,使用 Alpha 混合在画布上渲染当前帧(见下文)。如果当前帧没有 alpha 通道,假设 alpha 值为 255,这实际上相当于替换了矩形。
  • 1:不混合。处理上一帧后,通过覆盖当前帧覆盖的矩形在画布上渲染当前帧。

处理方法 (D):1 位
指示在画布上显示当前帧之前(在渲染下一帧之前)如何处理当前帧:

  • 0:请勿处置。将画布保留原样。
  • 1:处理为背景颜色。在当前帧覆盖的画布上,使用 ANIM 分块中指定的背景颜色填充矩形。

注意:

  • 帧处理仅适用于帧矩形,即由帧 X、帧 Y、帧宽度和帧高度定义的矩形。不一定会涵盖整个画布。
  • alpha 混合:
    假设 R、G、B 和 A 通道都是 8 位,并且 RGB 通道没有由 Alpha 值预乘,则用于 &‘dst’ 融合到 ‘src’ 的公式为:
blend.A = src.A + dst.A * (1 - src.A / 255)
if blend.A = 0 then
  blend.RGB = 0
else
  blend.RGB =
      (src.RGB * src.A +
       dst.RGB * dst.A * (1 - src.A / 255)) / blend.A
  • 应在线性颜色空间内进行 Alpha 混合,考虑图片的颜色配置文件。如果颜色配置文件不存在,系统会假定使用 sRGB。(请注意,由于灰度系数约为 2.2,sRGB 也需要进行线性处理。)

帧数据:数据块大小 - 16 字节
包括:

  • 帧的可选 Alpha 子区块。
  • 帧的比特流子分块。
  • 可选的未知分块列表。

注意:上述“ANMF’ 载荷”(帧数据)由各个 padding 分块组成,如 RIFF 文件格式所述。

Alpha 版

 0                   1                   2                   3
 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                      ChunkHeader('ALPH')                      |
|                                                               |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|Rsv| P | F | C |     Alpha Bitstream...                        |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

保留 (Rsv):2 位

必须为 0。读者必须忽略此字段。

预处理 ( P):2 位
这些信息性位用于指示在压缩过程中执行的预处理。解码器可以使用这些信息(例如,在显示值之前抖动值或平滑渐变)。

  • 0:未进行预处理
  • 1:降低等级

过滤方法 (F):2 位
使用的过滤方法:

  • 0:无。
  • 1:水平过滤器。
  • 2:垂直滤镜。
  • 3:渐变滤镜。

对于每个像素,系统都会使用以下计算进行过滤。假设当前 X 位置周围的 Alpha 值被标记为:

 C | B |
---+---+
 A | X |

我们试图计算位置 X 的 Alpha 值。首先,根据过滤方法进行预测:

  • 方法 0:predictor = 0
  • 方法 1:predictor = A
  • 方法 2:predictor = B
  • 方法 3:Predictor = clip(A + B - C)

其中,clip(v) 等于:

  • 如果 v 小于 0,则为 0
  • 255(如果升级;> 255)
  • v 否则

最终值是通过以下方式得出的:将解压缩值 X 添加到预测器,并使用模 256 算术将 [256-511] 范围封装到 [0-255] 中:

alpha = (predictor + X) % 256

在特殊情况下,最左边和最上方是像素位置:

  • 位置 (0,0) 处的左上角值使用 0 作为预测值。否则,
  • 对于水平或渐变过滤方法,系统将使用上面位置 (0, y-1) 预测位置 (0, y) 最左侧的像素。
  • 对于垂直或渐变过滤方法,系统会使用左侧的位置 (x-1, 0) 预测位置 (x, 0) 最顶部的像素。

解码器无需以任何指定的方式使用这些信息。
压缩方法 ©:2 位

压缩方法:

  • 0:未压缩。
  • 1:使用 WebP 无损格式进行压缩。

Alpha 位流:数据块大小 - 1 个字节

编码 Alpha 流。

此可选分块包含此帧的编码 Alpha 数据。包含 ‘VP8L’ 分块的帧不应包含此分块。

说明:透明度信息已包含在 &VP3 中。

Alpha 通道数据以未压缩的原始数据形式(压缩方法为 ‘0’)存储)或使用无损格式进行压缩(如果压缩方法为 ‘1’)。

  • 原始数据:由长度为 * 高度的字节序列组成,包含所有按扫描顺序排列的 8 位透明度值。
  • 无损格式压缩:字节序列是隐式尺寸宽度 x 高度的压缩图片流(如 WebP 无损比特流格式中所述)。也就是说,此图片流不包含任何描述图片尺寸的标题。

说明:其他来源已经知道该维度,因此再次存储该维度会造成冗余并容易出错。

将图像流解码为 ARGB 颜色值后,按照无损格式规范中所述的过程,必须从 ARGB 四元组的绿色通道中提取透明度信息。

说明:与其他规范不同的是,绿色通道可以在规范中使用额外的转换步骤,从而改善压缩效果。

比特流 (VP8/VP8L)

此区块包含单个帧的压缩比特流数据。

比特流分块可以是 (i) 使用“VP8”的 VP8 分块(请注意,第四个字符空间为显著空间)作为标记,或者 (ii) 使用“VP8L”分块作为它的 VP8L 分块。

VP8 和 VP8L 分块的格式分别在简单文件格式(有损)和简单文件格式(无损)部分进行了介绍。

颜色配置文件

 0                   1                   2                   3
 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                      ChunkHeader('ICCP')                      |
|                                                               |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
:                       Color Profile                           :
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

颜色配置文件:数据块大小字节

ICC 配置文件。

此区块必须出现在图片数据之前。

最多只能有 1 个此类分块。如果存在更多这样的区块,读者可以忽略除第一个区块之外的所有其他区块。如需了解详情,请参阅 ICC 规范。

如果此分块不存在,则应采用 sRGB。

元数据

元数据可以存储在 EXIF’XMP 或数据块中。

每种类型的数据块 (‘EXIF’ 和 'XMP ') 最多只能有一个块。如果有多个此类块,读取器可以忽略除第一个块之外的全部块。

区块的定义如下:

EXIF 分块:

 0                   1                   2                   3
 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                      ChunkHeader('EXIF')                      |
|                                                               |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
:                        Exif Metadata                          :
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

Exif 元数据:数据块大小字节

EXIF 格式的图片元数据。

XMP 分块:

 0                   1                   2                   3
 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                      ChunkHeader('XMP ')                      |
|                                                               |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
:                        XMP Metadata                           :
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

XMP 元数据:数据块大小字节

XMP 格式的图片元数据。

请注意 &X39;XMP ’ FourCC 中的第四个字符是一个 ASCII 空格 (0x20)。

如需了解有关元数据处理的其他指导,请参阅元数据工作组的元数据处理指南。

未知数据块

如果某个 RIFF 分块(如本部分中所述)与本文档中描述的任何分块不同,该分块会被视为未知分块。

说明:允许未知的分块为将来该格式的扩展提供配置,同时也允许存储任何特定于应用的数据。
一个文件可能包含未知的数据块:

  • 文件末尾,如扩展 WebP 文件标头部分中所述。
  • ANMF 分块的末尾,如动画部分中所述。
    读者应忽略这些区块。写入者应按其原始顺序保留这些块(除非它们明确打算修改这些区块)。

通过框架组装画布

在这里,我们概括介绍了读者在添加动画图片的情况下如何组合画布。

首先,使用 VP#XX 块中指定的尺寸制作画布,宽度为 Canvas Width Minus One + 1 像素,高度为 Canvas Height Minus One + 1 像素。'ANIM&S“数据块”中的 Loop Count 字段用于控制动画过程的重复次数。对于非零 Loop Count 值,此值为 Loop Count - 1;如果 Loop Count 为零,则为无限值。

在每次循环迭代开始时,画布会使用 &AN33;ANIM&B39; 分块中的背景颜色或应用定义的颜色填充。

‘ANMF’ 分块包含按显示顺序指定的单个帧。在渲染每一帧之前,系统会应用上一帧的 Disposal method

解码后帧的渲染以笛卡尔坐标(2 * Frame X、2 * Frame Y)开头,并以画布左上角作为原点。 使用 Blending method 在画布上呈现宽 Frame Width Minus One + 1 像素、高 Frame Height Minus One + 1 像素的图片。

画布会显示 Frame Duration 毫秒。这一过程会持续到显示 ANMF 块指定的所有帧。之后将开始新的循环迭代,如果所有迭代都已完成,画布将保持最终状态。

以下伪代码展示了呈现过程。表示法 VP8X.field 表示 ‘VP8X’ 分块中的字段,具有相同的说明。

assert VP8X.flags.hasAnimation
canvas ← new image of size VP8X.canvasWidth x VP8X.canvasHeight with
         background color ANIM.background_color.
loop_count ← ANIM.loopCount
dispose_method ← Dispose to background color
if loop_count == 0:
  loop_count = ∞
frame_params ← nil
assert next chunk in image_data is ANMF
for loop = 0..loop_count - 1
  clear canvas to ANIM.background_color or application defined color
  until eof or non-ANMF chunk
    frame_params.frameX = Frame X
    frame_params.frameY = Frame Y
    frame_params.frameWidth = Frame Width Minus One + 1
    frame_params.frameHeight = Frame Height Minus One + 1
    frame_params.frameDuration = Frame Duration
    frame_right = frame_params.frameX + frame_params.frameWidth
    frame_bottom = frame_params.frameY + frame_params.frameHeight
    assert VP8X.canvasWidth >= frame_right
    assert VP8X.canvasHeight >= frame_bottom
    for subchunk in 'Frame Data':
      if subchunk.tag == "ALPH":
        assert alpha subchunks not found in 'Frame Data' earlier
        frame_params.alpha = alpha_data
      else if subchunk.tag == "VP8 " OR subchunk.tag == "VP8L":
        assert bitstream subchunks not found in 'Frame Data' earlier
        frame_params.bitstream = bitstream_data
    render frame with frame_params.alpha and frame_params.bitstream
      on canvas with top-left corner at (frame_params.frameX,
      frame_params.frameY), using blending method
      frame_params.blendingMethod.
    canvas contains the decoded image.
    Show the contents of the canvas for
    frame_params.frameDuration * 1ms.
    dispose_method = frame_params.disposeMethod

文件布局示例

采用 Alpha 格式的有损编码图片可能如下所示:

RIFF/WEBP
+- VP8X (descriptions of features used)
+- ALPH (alpha bitstream)
+- VP8 (bitstream)

无损编码的图片可能如下所示:

RIFF/WEBP
+- VP8X (descriptions of features used)
+- XYZW (unknown chunk)
+- VP8L (lossless bitstream)

具有 ICC 配置文件和 XMP 元数据的无损图片可能如下所示:

RIFF/WEBP
+- VP8X (descriptions of features used)
+- ICCP (color profile)
+- VP8L (lossless bitstream)
+- XMP  (metadata)

包含 Exif 元数据的动画图片可能如下所示:

RIFF/WEBP
+- VP8X (descriptions of features used)
+- ANIM (global animation parameters)
+- ANMF (frame1 parameters + data)
+- ANMF (frame2 parameters + data)
+- ANMF (frame3 parameters + data)
+- ANMF (frame4 parameters + data)
+- EXIF (metadata)
<think>好的,我现在需要帮助用户解决移动端管理后台图片加载失败的问题。首先,用户提到了浏览器兼容性、图片路径问题和响应式设计这几个可能的原因,我需要逐一分析这些方面,并提供相应的解决方案。 首先,关于浏览器兼容性。移动端有各种不同的浏览器,比如Chrome、Safari、Firefox等,不同浏览器对HTML5或CSS3的支持可能有差异。特别是某些较旧的浏览器版本可能不支持新的图片格式,比如WebP。这时候,我需要考虑使用兼容性更好的图片格式,比如JPEG或PNG,或者通过检测浏览器支持情况来动态选择图片格式。另外,使用polyfill库也是一个解决办法,可以帮助在不支持的浏览器中实现某些功能。 接下来是图片路径问题。路径错误是常见的问题,特别是在开发环境中可能使用相对路径,而部署到服务器后路径结构发生变化,导致图片无法加载。需要检查图片的绝对路径和相对路径是否正确,尤其是在使用CDN或静态资源服务器时,路径配置是否正确。另外,文件名的大小写敏感问题也需要注意,特别是在Linux服务器上,文件名是区分大小写的,如果代码中的路径和实际文件名大小写不一致,就会导致加载失败。 然后是响应式设计的问题。移动端设备屏幕尺寸多样,如果响应式设计没有处理好,可能会导致图片无法正确适配。需要检查CSS媒体查询是否针对不同屏幕尺寸正确设置,图片容器是否有固定的宽高导致图片被裁剪或溢出。此外,使用srcset属性可以根据设备分辨率自动选择合适尺寸的图片,避免加载过大的图片影响性能,或者过小的图片导致模糊。 除了用户提到的这三个方面,还需要考虑其他潜在因素。比如网络问题,用户可能在弱网环境下加载图片失败,可以建议检查网络连接,或者添加加载超时和重试机制。缓存问题也可能导致图片无法更新,这时候需要设置合适的缓存策略,比如在文件名中添加版本号或时间戳来强制更新。另外,服务器配置错误,比如MIME类型未正确设置,或者图片文件权限问题,也可能导致图片无法加载,需要检查服务器日志和配置。 在解决方案中,每个问题点都需要具体的步骤。例如,针对浏览器兼容性,可以推荐使用Modernizr库检测浏览器支持情况,或者使用<picture>标签来提供多种格式的图片。对于路径问题,建议在代码中使用绝对路径,并在部署时进行全面的测试。响应式设计方面,可以展示如何使用媒体查询和srcset来优化图片显示。 此外,生成相关问题也是用户的需求之一,需要确保问题覆盖其他可能的原因,比如CDN配置、图片格式优化、服务器日志分析等,帮助用户全面排查问题。 最后,需要确保回答结构清晰,分点列出原因和解决方案,使用LaTeX格式时注意数学表达式的正确性,但在这个问题中可能涉及较少,主要是在代码块和引用格式上注意规范。同时,引用标识要自然地添加在相关段落末尾,尽管用户提供的引用内容为空,但可能需要根据实际情况添加注释。</think># 移动端管理后台图片加载失败原因及解决方法 ## 一、浏览器兼容性 1. **核心问题** iOS Safari 对 WebP 格式支持较晚(2020年后才完全支持),Android 旧版本浏览器可能不兼容 AVIF 格式[^1] 2. **解决方案** - 使用 `<picture>` 标签提供多格式备选方案: ```html <picture> <source srcset="image.webp" type="image/webp"> <source srcset="image.jpg" type="image/jpeg"> <img src="image.jpg" alt="fallback"> </picture> ``` - 添加特征检测 polyfill: ```javascript Modernizr.on('webp', (result) => { if (!result) document.documentElement.classList.add('no-webp') }) ``` ## 二、图片路径问题 1. **典型错误场景** 开发环境使用 `../assets/img.png` 相对路径,部署后路径层级变化导致404错误 2. **调试方案** - 使用浏览器开发者工具查看网络请求: - 按`F12` > `Network` > 筛选`Img`类型 - 检查状态码: - 红色`404`:路径错误 - 灰色`304`:缓存问题 - 动态路径拼接示例: ```javascript const basePath = process.env.NODE_ENV === 'production' ? 'https://cdn.example.com/' : '/assets/'; <img src={`${basePath}header.jpg`}> ``` ## 三、响应式设计缺陷 1. **常见适配问题** - 媒体查询断点设置不当(如仅针对768px设计,折叠屏设备显示异常) - 图片容器使用`height: 500px`固定值导致内容溢出 2. **最佳实践** ```css .responsive-image { width: 100%; height: auto; object-fit: contain; } @media (max-width: 480px) { .image-container { aspect-ratio: 16/9; } } ``` ## 四、进阶优化方案 1. **CDN配置检测** 通过`dig`命令验证CDN解析: ```bash dig +short cdn.example.com ``` 确保返回正确的CNAME记录 2. **格式优化建议** - 使用Squoosh工具压缩图片(保留EXIF信息) - 渐进式JPEG加载方案: ```php imagejpeg($image, null, 75); header('Content-Type: image/jpeg'); ``` 3. **服务端排查** - 查看Nginx访问日志: ```nginx tail -f /var/log/nginx/access.log | grep '\.jpg' ``` - 验证MIME类型配置: ```nginx types { image/webp webp; image/avif avif; } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值