跳至主要内容

第 21 章:HDR 與 Ultra HDR

傳統的數位影像一直被限制在 8 位元標準動態範圍 (SDR) 內:sRGB 色彩空間、100 尼特峰值亮度以及約 6 檔的可用對比度。現代手機感光元件卻能擷取 14 檔以上的動態範圍。直到最近,這些多餘的資訊都必須在 ISP(影像訊號處理器)中透過調低高光來「擠壓」進 8 位元 JPEG。Android 13 (API 33) 透過 DynamicRangeProfiles 引入了原生的 10 位元 HDR 影片支援,而 Android 14 (API 34) 則引入了革命性的 JPEG_R (Ultra HDR) 格式用於靜態照片。透過這些 API,你的應用可以產生能在現代 1,000+ 尼特螢幕上呈現極致亮度和深邃陰影的照片和影片。

本章實現了專案研究文件中《10 位元 HDR 與 Ultra HDR》部分的規格說明,包括 HLG 相容性、HDR10 靜態元數據注入以及 JPEG_R 增益圖 (gain map) 的生命週期。你可以使用 Android Camera Parameters 應用(Google Play)即時偵測每台設備的 HDR 性能:其 HDR 儀表板列出了支援的 DynamicRangeProfiles(如 HDR10HDR10_PLUSHLG),並根據 Android 14 CDD 15 級性能標準驗證 JPEG_R 的合規性。

SDR vs HDR:不僅僅是「更亮」

理解 HDR 需要區分兩個物理概念:位元深度 (Bit Depth)傳遞函數 (Transfer Function)

  • Bit Depth:SDR 使用每通道 8 位元(256 級)。HDR 使用 10 位元(1,024 級),消除了日落或純色背景中常見的色彩斷層(banding)。
  • Transfer Function (EOTF):SDR 使用伽馬曲線 (Gamma 2.2)。HDR 使用 HLG (Hybrid Log-Gamma)PQ (Perceptual Quantizer)。HLG 是向後相容的(在 SDR 螢幕上看起來正常);PQ(用於 HDR10)是非向後相容的,但在 HDR 螢幕上能實現更高的對比度。
規格SDR (sRGB)HLGHDR10 (PQ)Ultra HDR (JPEG_R)
位元深度8 位元10 位元10 位元8 位元 SDR + 10 位元增益圖
色彩空間Rec.709Rec.2020Rec.2020sRGB / Display P3
峰值亮度100 尼特1,000+ 尼特4,000+ 尼特視顯示器而定
相容性通用SDR 相容需要 HDR10 解碼器標準 JPEG 相容

第 1 步:查詢 10 位元 HDR 性能

要錄製 10 位元影片或預覽,相機必須在 REQUEST_AVAILABLE_CAPABILITIES 中宣告支援 DYNAMIC_RANGE_TEN_BIT

import android.hardware.camera2.CameraCharacteristics
import android.hardware.camera2.params.DynamicRangeProfiles

fun queryHdrProfiles(chars: CameraCharacteristics) {
val profiles: DynamicRangeProfiles? = chars.get(
CameraCharacteristics.REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES
)

if (profiles == null) {
Log.d("HDR", "此設備不支援 10 位元 HDR")
return
}

val supported = profiles.supportedProfiles
Log.d("HDR", "支援的 HDR 簡況: ${supported.joinToString()}")

// 檢查具體格式
val hasHlg = supported.contains(DynamicRangeProfiles.HLG)
val hasHdr10 = supported.contains(DynamicRangeProfiles.HDR10)
val hasHdr10Plus = supported.contains(DynamicRangeProfiles.HDR10_PLUS)
}
備註

HLG 是最通用的格式,因為它不需要複雜的元數據,且可以在大多數社交媒體應用上直接分享。HDR10+ 需要 HAL 進行逐幀元數據產生。

第 2 步:配置 10 位元輸出 Surface

在 Camera2 中,如果你想得到 10 位元輸出,必須在建立工作階段之前,透過 OutputConfiguration.setDynamicRangeProfile() 將該 Surface 的簡況設定為 10 位元模式。

import android.hardware.camera2.params.OutputConfiguration
import android.hardware.camera2.params.SessionConfiguration

fun create10BitSession(
cameraDevice: CameraDevice,
previewSurface: Surface,
recordSurface: Surface,
handler: Handler
) {
// 1. 針對預覽 Surface 配置 10 位元
val previewConfig = OutputConfiguration(previewSurface).apply {
dynamicRangeProfile = DynamicRangeProfiles.HLG
}

// 2. 針對錄製 Surface 配置 10 位元
val recordConfig = OutputConfiguration(recordSurface).apply {
dynamicRangeProfile = DynamicRangeProfiles.HLG
}

val sessionConfig = SessionConfiguration(
SessionConfiguration.SESSION_REGULAR,
listOf(previewConfig, recordConfig),
{ runnable -> handler.post(runnable) },
object : CameraCaptureSession.StateCallback() {
override fun onConfigured(session: CameraCaptureSession) {
// 此時管線將以 10 位元 Rec.2020 模式執行
startHdrPreview(session, previewSurface)
}
override fun onConfigureFailed(s: CameraCaptureSession) = Unit
}
)

cameraDevice.createCaptureSession(sessionConfig)
}

第 3 步:Android 14 Ultra HDR (JPEG_R)

JPEG_R 是目前行動端照片的最佳方案。它產生的是一个 .jpg 文件,內部包含一个標準的 8 位元 sRGB 影像(用於舊設備)和一个隱藏的 10 位元增益圖 (Gain Map)(用於新設備)。當在 Android 14+ 相簿中查看時,系統會根據螢幕的 HDR 性能,使用增益圖將高光部分的亮度「拉升」到極致。

配置 JPEG_R 擷取

這不需要特殊的工作階段,只需要一个支援該格式的 ImageReader

import android.graphics.ImageFormat

// 檢查是否支援 JPEG_R 格式 (API 34+)
val map = characteristics.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP)
val supportsUltraHdr = map?.getOutputSizes(ImageFormat.JPEG_R)?.isNotEmpty() ?: false

if (supportsUltraHdr) {
val ultraHdrReader = ImageReader.newInstance(
width, height, ImageFormat.JPEG_R, 2
)

// 在擷取請求中添加目標
val captureBuilder = cameraDevice.createCaptureRequest(
CameraDevice.TEMPLATE_STILL_CAPTURE
).apply {
addTarget(ultraHdrReader.surface)
// JPEG_R 會自動產生增益圖,無需手動干預 ISP
}
}

JPEG_R 增益圖原理 (Mermaid)

HDR 錄製的性能與溫控

錄製 10 位元影片會顯著增加 ISP 和記憶體控制器的負載:

  • 頻寬:10 位元數據的總位元量比 8 位元多 25%。
  • 溫控:在 4K@60 HDR 模式下,入門級手機可能會在 5-10 分鐘內觸發熱保護。
  • 儲存:必須使用 HEVC (H.265) 編碼器,因為 AVC (H.264) 在 Android 上通常不支援 10 位元簡況。

小結

本章涵蓋了現代 Android HDR 體系結構的兩大支柱:

  • DynamicRangeProfiles:用於 10 位元影片,核心是 HLG(相容性好)和 HDR10(對比度高)。
  • JPEG_R (Ultra HDR):用於靜態照片,在標準 JPEG 中嵌入 10 位元增益圖,實現完美的高光回放。
  • 配置要點:透過 OutputConfiguration.setDynamicRangeProfile() 為每個輸出開啟 10 位元模式。
  • 光照要求:HDR 依賴於感光元件擷取的多餘動態範圍,在極暗環境下 HDR 效果並不明顯,但在日落、海灘等高光比場景中效果驚人。

下一章

在第 22 章中,我們將學習如何利用 OEM 的專有演算法:相機擴充 (Camera Extensions)。你將了解如何呼叫廠商內建的夜景模式 (Night)、人像模式 (Bokeh) 和 HDR 融合,這些功能通常比直接使用 TEMPLATE_STILL_CAPTURE 能提供更好的畫質。

你可以透過 Android Camera Parameters 應用驗證你手機的 HDR 設定檔支持情況,看看它是否符合 Android 14 旗艦級的 Ultra HDR 標準。