Skip to content

Add support for Ultra HDR #8036

Open
Open

Description

@cmahnke

I would like to suggest to add the addition of the Ultra HDR format as a new way to read and write HDR images.

From a technical point of view it's similar to the MPO format, that it's a JPEG image, containing an additional data stream. In case of Ultra HDR this data stream is a gainmap.

This way a reader implementation not aware of Ultra HDR only sees the SDR JPEG image.

There are currently several open enhancement requests to add the format to various well (and less well known) libraries and tools:

There is also a library

Activity

  1. radarhere commented on Jun 25, 2024

    @radarhere
    Member

    Are you aware of any small images (under 500kb) images that could be added to our test suite and distributed under the Pillow license?

  2. cmahnke commented on Jun 25, 2024

    @cmahnke
    Author

    @radarhere: It's possible to generate one using libultrahdr. What are the requirements, does it have to be somehow very colorful or something like that?

    If it needs to be beautiful @gregbenz might be able to help out.

  3. gregbenz commented on Jun 25, 2024

    @gregbenz

    @cmahnke Happy to answer any questions here. I'm not clear what the intended use of this library/feature is. I'd be happy to consider any requests for a few sample images, though for testing code I would recommend creating dedicated test images to most easily and reliably validate results.

    Is the goal here to alter the image (resize, compress, crop, rotate, flip), convert to another image format as is, filter, or to render for display? The first couple are well supported by libultrahdr and I'm assuming that's probably the intent here.

    If you start changing image content (such as filtering), you'll have to get more involved (things can get pretty tricky and some edits would only be suitable if you're willing to render to SDR / HDR and give up the adaptive nature of a gain map). And actual display (such as in a browser) involves linear interpolation between the base SDR and full HDR rendering as appropriate for the encoding of the image relative to the display's available HDR headroom.

    I have seen numerous issues with various efforts to render or transcode gain maps (improper alteration of metadata, gain map artifacts, scaling of the images before merge causing edge artiffacts, etc). If libultrahdr meets your needs, I would recommend leveraging that rather than trying to build the capability from scratch. It is supported by Google (who has been very supportive of gain maps in both Chrome and Android), well maintained, and aligned with efforts towards an official ISO standard for common file formats (supports JPG now, but the project team has mentioned AVIF / HEIF on the roadmap).

    For anyone who has questions on gain maps, I have lots of information at https://gregbenzphotography.com/hdr-photos/jpg-hdr-gain-maps-in-adobe-camera-raw/ and https://gregbenzphotography.com/hdr/.

  4. javilm commented on Sep 17, 2025

    @javilm

    @radarhere I found this thread because I use Pillow to process images on my site and I wanted to add support for HDR.

    I can "donate" some of my HDR photos. How do we proceed?

    I'd like to see HDR support in Pillow instead of having to rewrite the image processing code with ImageMagick.

  5. radarhere commented on Sep 17, 2025

    @radarhere
    Member

    It's not all that clear to me what the goal of this issue is.

    If the goal is just to load the basic JPEG data as an image, then it is possible that this was resolved by #8056 in Pillow 10.4.0. If someone has an image that isn't able to be processed in that way by Pillow, please attach it to demonstrate.

    If the goal is to load something more advanced from an image, then it would be helpful if someone could attach an image and describe what they would like to see when Pillow reads it.

  6. reagle commented on Aug 12, 2026

    @reagle

    I think the ambiguity @radarhere flagged comes down to two different asks that this thread has conflated:

    1. "Can Pillow open an Ultra HDR JPEG without erroring?" — Yes, this looks resolved. Ultra HDR/gain-map JPEGs are valid MPO-style files (base SDR image + auxiliary gain-map image via MPF), and Image.open() reads the base image fine.
    2. "Does the gain map survive Pillow's normal resize/save pipeline?" — No, and this is the part that actually affects real usage. Any tool that does the standard Image.open() -> resize -> save() (thumbnailers, gallery generators, CMS upload pipelines) silently drops the gain map with no error or warning. The output is a flattened SDR JPEG that looks like a successful, lossless-ish resize — nothing signals that HDR data was discarded.

    Repro (Pillow 12.3.0, current as of this writing):

    from PIL import Image
    from pilkit.processors import ResizeToFit  # or any resize path
    
    img = Image.open("ultrahdr.jpg")
    print(img.format)        # MPO
    print("mp" in img.info)  # True -- Pillow *does* parse the MPF/gain-map segment into img.info
    
    img2 = ResizeToFit(1152, 1100).process(img)
    img2.save("out.jpg", quality=85)
    # out.jpg: gain map is gone. exiftool confirms no MPImage/MPImageLength on the output,
    # vs. several MB of MP Image 2 data on the source.

    So Pillow already parses enough to know a gain map is present (img.info['mp']), it just never re-attaches it on save. That's a narrower, more tractable ask than full gain-map editing support (which @gregbenz's comment correctly notes gets complicated fast) — even just preserving the gain map unmodified when the base image is resized would cover the common case (most resizes don't need to touch the gain map's tone curve, just its dimensions).

    Failing that, a UserWarning when save() drops a known gain map would at least stop this from being a silent data-loss bug for anyone using Pillow as a generic image-processing step (that's my case — I ran into this via sigal, a static gallery generator that uses Pillow for exactly this resize-and-save pattern).

    Happy to attach a minimal reproducer file if that would help.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions