一、原理:
1️⃣什么是HDR显示(XDR)?
影像实践中,HDR显示(苹果一般用XDR表示,后续我们使用XDR代替HDR显示概念,以区分HDR图像或者HDR技术)一般表示超高动态范围显示。XDR显示与Dislpaly相关,一般与谷歌标准的UltraHDR为相似含义。此概念由苹果提出,用于区分XDR与传统HDR的显示区别,后被行业广泛采用用于表示区别于传统的超高动态范围显示。简单说,XDR就是一种HDR显示技术,用于显示高Bit的图像来增强显示的动态范围。
在本博客中,我们重点讨论XDR显示的全流程,从拍摄到最终显示的过程,尤其是安卓管线的重点部分。同时简单介绍我个人开发的XDR工具。
What is HDR?
2️⃣图像XDR的方式有哪些?
自谷歌发布UltraHDR以来(Google Ultra HDR 图片格式 v1.1,官方文档),通过Gainmap形式嵌入图像格式来还原和读取高Bit信息还原原始HDR信息已经成为事实标准,尤其是在安卓上,JPG+Gainmap的形式成为主流的XDR显示的图像格式。SDR + Gain Map合并封装为的图像格式,最终以传统SDR+Gainmap的封装文件形式已经成为当前行业的主流标准和形式。包括苹果使用的Adaptive HDR也是遵循类似技术标准(WWDC2024 Session: Use HDR for dynamic image experiences in your app )。
3️⃣XDR的意义:通过Gainmap还原高Bit场景下的丰富信息、更加连续的影调和过渡、更高的亮度。
我们用更简化的思维描述就是,传统的8bit 0-255的SDR图像只能表示256个数值或者亮度等级,而且XDR图像和显示则可以拓展显示的内容数据位宽,从而使用更多的亮度等级,来提供更加丰富和连续的影调和过渡。以Google Ultra HDR官方推荐为例子,在传统8bit图像增加2bit的gainmap图来拓展最终显示内容到10bit,从而提供更多的亮度等级,来还愿原始世界的光比和动态。

4️⃣XDR从拍摄到显示的链路
以安卓为例,从拍摄到显示的全链路控制流程
⚠️注意下图,核心和精华都在下图中⚠️
————————————————————————————————————————————————
🌟第一阶段:拍摄 (Capture) —— 【内容亮度:理论的照片亮度】
这是物理世界光线转化为数字信号的过程:
数据采集:相机传感器获取原始 RAW 数据。
前处理:转化为 高Bit RGB 信号(保留原始光影的高动态范围)。
计算增益:
Tone Mapping:在相机的ISP链路中,尤其是RAW域处理中,传统SDR图是通过色调映射将高Bit数据压缩为标准的 8Bit YUV 图像保证兼容性,但是也损失了影像的动态范围和原始的部分高亮信息。
Gainmap 生成:这里便是相机链路总,XDR图像的精华算在,通过拿到高Bit RGB(或者RAW域)总之是Tone压缩之前的数据或者照片流的关键节点,计算与8Bit YUV之间的亮度比,生成一张 Gainmap(增益图),并存储,来达到还原原始的高动态范围。
🌟🌟第二阶段:编码 (Encoding) —— 【内容存储】
将图像和元数据封装为标准文件格式(Google UltraHDR):
元数据注入:遵循 ISO 21496-1 标准写入 HDR 元数据。
双层容器封装:
主图层:存储标准 JPEG-SDR 数据。
嵌入层:在 APP2 等元数据段中嵌入 Gainmap-SDR 数据。
结果:生成一张在旧设备看是普通照片,新设备看是 XDR 的 JPG 文件。
🌟🌟🌟第三阶段:解码和渲染 (Decoding & Rendering) —— 【转换区】
系统读取文件并准备显示:
位图解码 (Bitmap):
解码为 RGBA_F16 格式的 HDR Bitmap。
提取 baseImage (SDR Linear RGB) 和 gainMap。
映射至 Extended Linear (scRGB) 色彩空间,并标记 hdrFlag: true。
👍合成预览 (SurfaceFlinger):
核心公式计算:依据理论公式 HDR_target = SDR_base × GainMap × min(contentHeadroom, displayHeadroom) 计算理论显示亮度。
⚠️注意,此时的数据仍然是理论上的HDR亮度,还是内容亮度,而不是最终的显示亮度。⚠️
👍Android 系统合成引擎(SurfaceFlinger):
最终安卓的合成准备,将图层信息交给硬件。
⚠️注意,此时的数据是理论HDR显示亮度,也就是安卓基于屏幕素质和能力以及基础设定,计算出来的理论显示亮度,而不是最终的显示亮度。
🌟🌟🌟🌟第四阶段:显示 (Display) —— 【屏幕亮度:物理亮度】
最终将信号转化为像素点发光:
硬件合成 (HWC):
指令转换:HWC(硬件合成器)将 SurfaceFlinger 的“HDR 意图”翻译为底层的硬件指令。
路径决策:根据当前功耗、温度(ABL/Thermal)决定走“硬件直通”还是“GPU 渲染”。
硬件驱动控制:
像素驱动:控制每一个子像素的开关。
亮度电流:控制背光或 OLED 自发光电流。
局部调光 (Local Dimming):实现精准的黑白对比。
最终校准:通过 屏幕 Gamma LUT 进行最后的色彩和亮度补偿。
⚠️注意,此时的数据是理论HDR最终实际显示亮度,也就是安卓最终呈现出来的屏幕显示亮度,这是基于安卓的屏幕硬件能力,以及安卓的显示设置等最终的综合控制结果。
二、如何控制XDR?
1️⃣基础的三个控制参数
记住下面的核心公式,后续我们所有控制都是围绕下面公式展开:
HDR_target = SDR × Gain × min(content, display)
核心外部参数
- SDR 白点亮度 (LsdrLsdr):500 nits。
- 这是当前屏幕亮度设置下,普通内容(Standard Dynamic Range,如UI、普通网页)显示的亮度。
- 内容增益 (Gaincontent_Gaincontentmax):1-16倍。
- UltraHDR 照片中,Base Image 像素值为 255(SDR最白),Gainmap 指示该点需要提亮 1-16 倍(最大4档已经是目前99%显示设备的极限)。
- 屏幕最大增益能力 (Headroomdisplay_Gaincontentmax):4.0倍。(目前旗舰手机的极限)
- 这是当前硬件状态下,屏幕能提供的最大HDR峰值亮度相对于SDR白点的倍数。


总结一下就是,SDR代表传统的8bit图像的基础亮度,决定了整图的亮度基础。Gain代表原始图像上每个像素点的基础增益,决定了整图的理论内容亮度。min(content, display)代表和最终屏幕显示能力相关的最终照片被显示出来的物理亮度。
- 这是当前硬件状态下,屏幕能提供的最大HDR峰值亮度相对于SDR白点的倍数。
2️⃣显示参数
Min_lastDisplayResult(Dispalytentmax,Gaincontentmax)——取屏幕显示和内容增益的更小的值
这是是基于屏幕实际显示能力的范围,来限制内容增益,调整最终的显示动态范围,以避免过曝或者兼容屏幕实际能力。相对于在XDR显示上做了XDR的内容Tonemapping,而这个Tonemapping往往带有厂商的显示和审美倾向。
主要OEM厂商的实现差异:(来自AI,暂未确定):
| 厂商 | kneeStart | Roll-off 曲线 | 特点 |
|---|---|---|---|
| Google Pixel | 0.8 × DisplayIntentMax | BT.2390 变体 | 强调色彩准确度,优先保护肤色 |
| Samsung | 0.7 × DisplayIntentMax | 自定义 S-curve | 更激进的亮度提升,高光「明亮」但可能过曝 |
| OnePlus/OPPO | 0.65 × DisplayIntentMax | 分段线性+指数 | 侧重对比度,暗部提亮明显 |
| Xiaomi | 0.72 × DisplayIntentMax | 仿胶片曲线 | 注重「胶片感」,高光 roll-off 较平缓 |
3️⃣Headroom的概念和转化
Headroom/Gaincontentmax
苹果Adaptive HDR语境下的Headroom表示为HDR直方图的“档位”,此处Headroom档位和Gainmapratio是对数关系,即为:
log2(Gainmapratio) = Headroom(DXO)
敲重点:“档位”和“增益值”是等价的,“档位”代表对数关系,“增益值”代表线性关系。
只要理解了这里的转换,后续无论在什么语境遇到各种Headroom,增益值,白点比等概念,都可以轻松转换了,通过这里的转换即可以适用各种情况和语境,从而对齐不同的标准下的“余量”。
三、XDR工具
最后简单的介绍一下我写的XDR工具,主要用于影像实践中的XDR显示内容优化部分,有三个核心功能:1.提取Gainmap 2.写入Gainmap 3.转化SDR到XDR的映射曲线。(暂未开源,后续我会开源到github)。
1.提取Gainmap
通过Swift官方ADK,提取JPG和HEIF的EXIF中的嵌入的Gainmap图。
2.写入Gainmap
通过Swift官方ADK,将Gainmap图写入JPG和HEIF的EXIF中指定位置,⚠️注意,此处Swift官方ADK默认为gamma1.0,因为会对图像做gamma处理,因此写入gainmap需要进行degamma处理。
3.转化SDR到XDR的映射曲线
根据Gainmap计算理论内容亮度,遍历所有像素点,计算8bit下的SDR到高Bit XDR图的映射关系。
附带各厂商SDR到XDR的映射曲线
