构建PNG解析器:从二进制数据到HDR编辑

背景

W3C PNG V3 支持 HDR、APNG、Exif

HDR(High Dynamic Range):一种图形格式,能够存储具有相对较高动态范围的图像,该动态范围类似于或超过人类视觉系统的瞬时动态范围

动态范围: 最亮的颜色和最暗的颜色之间的亮度差异。 动态范围以摄影光圈数来衡量。一光圈代表亮度增加一倍。

Animated PNG (APNG): 扩展只有静态类型的 PNG,增加基于帧的动画。旨在代替 GIF 格式,支持 24 位的图片和 8 位的透明通道

民间标准转正了~ APNG 是无损动画序列的良好选择(GIF 性能较差)。AVIF 和 WebP 性能更好,但浏览器支持较少。

EXIF (Exchangeable image file format) :可交换图像文件格式,记录例如快门速度、光圈和方向 等等拍摄信息和图片属性

图片有哪些信息

一张图片除了包含每个像素点的数据之外,还有很多和解码、渲染相关的数据

图片类型

缩写首次发布类型MIME 类型扩展名标准 / 开发组织免费性描述
ICO1985图标容器(位图 / PNG)image/x-icon.icoMicrosoft免费透明 ✅。适合多尺寸图标(如 favicon)。
GIF1987无损(索引色,支持动画)image/gif.gifCompuServe / 公共领域免费动画 ✅。适合简单动画和低色彩图像。
BMP1987无损 / 通常无压缩image/bmp.bmp, .dibMicrosoft免费适合兼容性需求,文件大,不适合网络传输。
JPEG1992有损压缩image/jpeg.jpg, .jpeg, .jfif, .pjpeg, .pjpISO/IEC 10918-1免费适合照片类图像,文件小但无透明。
PNG1996无损压缩,支持透明image/png.pngW3C免费透明 ✅。适合高质量图像和透明需求。
SVG1999矢量(基于 XML)image/svg+xml.svgW3C免费透明 ✅ / 动画 ✅。适合图标、UI、图表,支持无限缩放。
WebP2010有损 / 无损、支持动画image/webp.webpGoogle免费透明 ✅ / 动画 ✅。适合替代 JPEG/PNG/GIF,压缩更优。
HEIF2015容器(可存储 HEVC 等)image/heif, image/heic.heif, .heicMPEG / ISO部分专利透明 ✅ / 动画 ✅ / HDR ✅。适合高效存储与 HDR 图像,常用于苹果设备。
AVIF2019有损 / 无损、支持动画image/avif.avifAOMedia(基于 HEIF 容器)免费透明 ✅ / 动画 ✅ / HDR ✅。适合高效压缩、HDR 与透明动画场景。

图片宽高

颜色类型

一种图片格式可能有多种颜色类型,如 PNG 的灰色,彩色,调色盘索引色,带透明彩色等等

色彩空间

可以理解为一个三/四维的坐标系,用于准确描述颜色,一个颜色在不同空间有不同表达。常见色彩空间有 sRGB、Display-P3

  • 色彩模型:将色彩表示为三个基本成分(红色、绿色和蓝色色彩通道)的混合,产生各种色调。如 RGB、HSL,HWB 等等
  • 色彩空间:基于某个色彩模型,定义了的基准,白点,传递函数等等的 “坐标系”
  • 色域: 色彩空间能够覆盖的颜色范围

显示器的色彩空间可以通过切换描述文件(ICCP)来调节

像素点颜色数据

位深度

一个颜色对应的存储 bit 位数,也可能是 调色盘索引的位数

编码解码信息

提取、过滤、压缩、分块等等处理信息

图片元数据

  1. EXIF(Exchangeable Image File Format) 拍摄参数:快门速度、光圈、ISO、焦距 设备信息:相机品牌、型号、镜头信息 时间信息:拍摄时间、修改时间 GPS信息:经纬度、海拔 DPI信息

  2. IPTC 版权信息:作者、版权声明 描述信息:标题、说明、关键词 新闻相关:记者、编辑、发布机构

  3. 其他技术元数据: ICCP(颜色配置文件) 缩略图数据 文件创建/修改时间

数据结构

我们以 PNG 为例子,看看上面的数据是如何存储的.

根据 PNG标准文档可以看到,PNG 有数据块的概念,一个图片数据有很多的 chunk 构成。

典型的PNG数据包括四部分

  • PNG Signature(PNG 签名块,包含 PNG 类型的标识)
  • IHDR(图像头部块,包含图片的宽度、高度、位的深度和颜色类型)
  • IDAT(图像数据块,像素压缩后的数据)
  • IEND(图像结束块,PNG 结束标识)

在此基础上,增加acTL(动画控制块)、fcTL(帧控制块)、fdAT(帧数据块)即为APNG动图格式。

我们使用一些工具查看图片二进制格式,可以看到一些数据

当然,想要更丰富的信息,还需要有很多种类型的 chunk 去承载,PNG 将 chunk 分类成了关键块和辅助块,关键块是图像展示的必要信息。

关键块 (Critical chunks)

chunktype允许多个可选位置含义
IHDR第一个图像头:宽、高、位深、颜色类型、压缩/滤波/隔行方式
PLTE第一个 IDAT 之前调色板(索引色或推荐调色板)
IDAT多个连续图像数据(DEFLATE 压缩流)
IEND最后一个图像结束标记

辅助块 (Ancillary chunks)

chunktype允许多个位置含义
acTLIDAT 之前APNG 动画控制(帧数、循环次数)
cHRMPLTE 和 IDAT 之前原色与白点的色度坐标
cICPPLTE 和 IDAT 之前颜色指示参数(原色、传递函数、矩阵系数的参数化描述,用于HDR等)
gAMAPLTE 和 IDAT 之前图像伽马(近似传递函数)
iCCPPLTE 和 IDAT 之前嵌入 ICC 配置文件(与 sRGB 互斥)
mDCVPLTE 和 IDAT 之前母版显示器色彩体积(原色、白点、最小/最大亮度等,HDR 相关)
cLLIPLTE 和 IDAT 之前内容亮度级信息(MaxCLL/MaxFALL,HDR 相关)
sBITPLTE 和 IDAT 之前每通道有效位数
sRGBPLTE 和 IDAT 之前指定 sRGB 与渲染意图(与 iCCP 互斥)
bKGDPLTE 之后;IDAT 之前建议背景色
hISTPLTE 之后;IDAT 之前调色板直方图(各索引出现频次)
tRNSPLTE 之后;IDAT 之前透明度信息(在无显式 alpha 时提供)
eXIfIDAT 之前EXIF 元数据(拍摄参数、时间、GPS 等)
fcTL仅第一个可在 IDAT 之前;其余在 IDAT 之后APNG 帧控制(每帧尺寸、位置、延时、处置/混合方式)
pHYsIDAT 之前像素物理密度/比例(每单位像素数与单位)
sPLTIDAT 之前建议调色板(含样本与频次)
fdATIDAT 之后APNG 帧数据(类似 IDAT 的附加帧负载)
tIME任意位置最后修改时间(UTC)
iTXt任意位置国际化文本(UTF‑8,可含语言/翻译,支持压缩)
tEXt任意位置文本键值对(未压缩)
zTXt任意位置压缩文本键值对

编程处理图像(web举例)

我们可以获取图片信息,可视化,编辑吗,做一个 web 简单的编辑器?

解码并可视化

查看 hdr APNG 和 exif,

    parse(buffer) {
        this.fileBuffer = new Uint8Array(buffer);
        this.chunks = [];

        if (!this.validatePNGSignature()) {
            throw new Error('不是有效的PNG文件');
        }

        let offset = 8; // signature len
        while (offset < this.fileBuffer.length) {
            const chunk = this.parseChunk(offset);
            if (!chunk) break;

            this.chunks.push(chunk);
            offset += chunk.totalSize;

            if (chunk.type === 'IEND') break;
        }

        return {
            chunks: this.chunks,
            header: this.header,
            fileSize: this.fileBuffer.length
        };
    }

项目在线地址

新特性的实现 && 所在位置

HDR :

  • cICP 实现

  • iCCP 实现

CICP 最初是为视频工作流程中的色彩空间信号传输而开发的,也用于 HEIF、AVIF 和 JPEG-XL 等图像格式。CICP 更加紧凑,旨在指示特定数学表示的原色、传递函数、矩阵系数和信号量化的使用情况,而 ICC 配置文件最初是为了在不同介质(显示、打印、扫描)之间匹配颜色而创建的。存储空间差距也很大

APNG: fcTL、fdAT

编辑图像

我们以修改图片 HDR 效果为例子

PNG 允许使用两种 HDR 格式: HLG 和 PQ [ ITU-R-BT.2100 ]。

我们只需要修改/构建 图片的 cICP 块,就可以使得图片支持 HDR 的功能

[ITU-R-BT.2100]符合国际电信联盟的标准 ITU-R BT.2100,BT 系列:广播业务(电视)。用于制作和国际节目交换的高动态范围电视图像参数值 。国际电信联盟,2018 年 7 月。网址: https ://www.itu.int/rec/R-REC-BT.2100

总结

从 PNG 新规范到图片相关知识,最后动手编辑 PNG 数据,算是从 0 到 1 简单学了一遍。感叹 PNG 良好扩展性的同时,也欣赏它被迫跟上时代的伟大自救精神~

项目仓库

参考资料