Posted on Mon 26 May 2025

HDR Photography

Estimates for the dynamic range (the maximum perceivable contrast between light and dark) of human eyes vary depending on the source, from 1:100 to 1:1000 or more for static contrast. Dynamic contrast, where the eye moves around the scene and the iris adjusts in size is many orders of magnitude larger - with sufficient adaption time we can switch between bright daylight (10^8 cd/m^2) and faint starlight (10^{-6} cd/m^2), a range of 10^{14}!

In comparison, standard computer screens display images encoded using 8-bit color channels, for a maximum of 256 brightness levels. This is why photos of very vivid scenes often appear washed out!

Yet modern mirrorless cameras are actually capably of capturing a much larger dynamic range, even exceeding the static contrast of human eyes: my Sony a7R V reaches up to 14.8 EV, a contrast of 1:2^{14.8} ~ 1:28526.

If you've bought any recent mobile phone or laptop you've probably also been exposed to the manufacturer's breathless marketing:

The eye-popping Liquid Retina XDR display offers 1,600 nits peak HDR brightness and now provides up to 1,000 nits of brightness for SDR content in bright light so you can see what’s on your screen more clearly outside. In low-light situations, it dims to 1 nit so you can work comfortably in darker spaces.

If we can capture images with such high color depth, and these displays supposedly have such an amazing brightness range, can we actually make use of all this expensive technology and view the full range of color in our photos?

Yes! Or at least kind of, with some hacks. There are image formats such as AVIF that support HDR 10- and 12-bit color depth. And they do look great, at least in Chrome on desktop. Unfortunately Apple, the very company that loves to harp on about its amazing displays, does not actually support HDR AVIF images in Safari - neither on Mac OS nor on iOS!

Fortunately there is a workaround: encode the image as a single-frame, looping HDR video. A fitting irony, given that AVIF is derived from the AV1 video codec.

Putting this all together, here are two examples with recent photos I happened to have to hand. Tap to switch between standard and high dynamic range:

If you have a modern device with an HDR-capable screen you should see a noticeable difference between the HDR and SDR version - significantly brighter highlights, without losing graduation in the shadows.

Editing

I used Adobe Lightroom to edit and export HDR version of my raw photos, saving them as AVIF.

I then used ffmpeg to produce the HDR video from the HDR AVIF for Safari:

ffmpeg -i hdr_image.avif -c:v libx265 -tag:v hvc1 -crf 18 -preset slow \
  -pix_fmt yuv420p10le -colorspace bt2020nc -color_trc smpte2084 \
  -color_primaries bt2020 -t 1 -movflags +faststart hdr_video.mp4

Note: image height and width must each be divisible by 2, otherwise the conversion will fail:

[libx265 @ 0x153005af0] Cannot open libx265 encoder.
[vost#0:0/libx265 @ 0x153005690] Error while opening encoder - maybe incorrect parameters such as bit_rate, rate, width or height.
[vf#0:0 @ 0x153006530] Error sending frames to consumers: Invalid data found when processing input
[vf#0:0 @ 0x153006530] Task finished with error code: -1094995529 (Invalid data found when processing input)
[vf#0:0 @ 0x153006530] Terminating thread with return code -1094995529 (Invalid data found when processing input)
[vost#0:0/libx265 @ 0x153005690] Could not open encoder before EOF
[vost#0:0/libx265 @ 0x153005690] Task finished with error code: -22 (Invalid argument)
[vost#0:0/libx265 @ 0x153005690] Terminating thread with return code -22 (Invalid argument)
[out#0/mp4 @ 0x153004b90] Nothing was written into output file, because at least one of its streams received no packets.

Tags: photography, hdr

© Julian Schrittwieser. Built using 開板. Theme by Giulio Fidente on github. .