Мне нужно правильно преобразовать входное цветовое пространство HDR в SDR (цветовое пространство SRGB или P3, подходящее для низкой битовой глубины JPG). Это должно быть возможно, поскольку управление цветом Apple уже поддерживает это. Например, при попытке отобразить исходное изображение JXL в любом месте macOS с правильным управлением цветом на дисплее SDR результат будет правильным.
Поскольку я хотел бы поддерживать очень большие (61MP+) изображения с разрешением 10 или 16 бит на канал, я пытаюсь использовать ImageIO (
Код: Выделить всё
CGImageSource
Мы будем рады любым предложениям.
Обратите внимание, что эти файлы на самом деле представляют собой файлы с расширенным динамическим диапазоном, а не то, что раньше называлось/известно как « HDR-фотография», которая объединяет несколько экспозиций в обычное изображение SDR.
Вот что у меня есть на данный момент:
Код: Выделить всё
guard let data = sourceImageData,
let source = CGImageSourceCreateWithData(data as CFData, [kCGImageSourceShouldCache: false, kCGImageSourceTypeIdentifierHint: asset.uniformType.identifier as CFString] as CFDictionary),
let cfOutputData = CFDataCreateMutable(nil, 0),
let imageDestination = CGImageDestinationCreateWithData(cfOutputData, outputUTType.identifier as CFString, 1, nil) else {
break
}
var outputOptions: [AnyHashable: Any] = [kCGImageDestinationMergeMetadata: true,
kCGImageDestinationLossyCompressionQuality: options.outputLossyCompressionQuality,
kCGImageSourceCreateThumbnailFromImageAlways: true,
kCGImageSourceCreateThumbnailWithTransform: true]
if case let .scaled(scale) = options.outputResize {
outputOptions[kCGImageDestinationImageMaxPixelSize] = Double(max(asset.pixelWidth, asset.pixelHeight)) * scale
} else if case let .aspectResized(maxPixelSize) = options.outputResize {
outputOptions[kCGImageDestinationImageMaxPixelSize] = maxPixelSize
}
if [.jpeg /* and other 8bpc formats */].contains(options.outputDataFormat) {
outputOptions[kCGImageSourceDecodeRequest] = kCGImageSourceDecodeToSDR
outputOptions[kCGImageDestinationPreserveGainMap] = false
outputOptions[kCGImagePropertyNamedColorSpace] = CGColorSpace.sRGB
} else {
outputOptions[kCGImageSourceDecodeRequest] = kCGImageSourceDecodeToHDR
outputOptions[kCGImageSourceDecodeRequestOptions] = [
"kCGFallbackHDRGain": 10000,
"kCGTargetColorSpace": CGColorSpace.itur_2100_PQ,
"kCGTargetHeadroom": 1000000
]
}
CGImageDestinationAddImageFromSource(imageDestination, source, 0, outputOptions as CFDictionary)
if CGImageDestinationFinalize(imageDestination) {
imageData = cfOutputData as Data
}
Интересно, что HDR-изображения, снятые на iPhone, не находятся в цветовом пространстве BT.2100 (или другом HDR), а представляют собой композицию базового изображения P3 со слоем метаданных карты усиления, который я могу правильно обработать с помощью kCGImageDestinationPreserveGainMap = false< /code>.
Вот пример файла HDR JXL:
https://www.dropbox.com/scl/fi/ p9bpuuykjgtwaeax7cfyc/orig.jxl?rlkey=w48cx1av2p2uzbt8m39luq2bb&st=bnrcpkg3&dl=0
Если вы откроете это в macOS 15.0+', просмотрите на современном MacBook Pro или на подходящем HDR-дисплее, например Pro Отобразите XDR, вы должны увидеть весь динамический диапазон. В macOS до Sequoia функция предварительного просмотра не была настроена для отображения изображений HDR; в этом случае вы можете импортировать изображение в «Фото», где диапазон HDR должен отображаться правильно. JXL поддерживается в macOS 14 и более поздних версиях, iOS 17 и более поздних версиях.
Некоторые (неправильные) примеры вывода:
ImageIO

Поскольку это не изменило цветовое пространство вообще, цветовое пространство этого JPG — BT.2100, и вы можете видеть постеризацию (цветовые полосы), возникающую из-за низкой битовой глубины.
Основное изображение

Здесь цветовое пространство SRGB было правильно присвоено изображению, но тональная компрессия не выполнялась, поэтому цвета неправильные.
Приложение «Фотографии»
Неудивительно, что если приложение «Фотографии» используется для копирования (CMD+C) изображения JXL, оно создает JPG цветового пространства P3 с правильным тональным отображением и плавными градиентами.
Любые советы о том, как достичь того, что мне нужно, приветствуются. Спасибо
Подробнее здесь: https://stackoverflow.com/questions/790 ... ng-imageio