grapeot / AppleJPEGGainMap

Reference implementation to embed a gain map to an SDR photo so it renders as HDR on iPhones and Macs.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Gain Map orientation

dr-tam opened this issue · comments

commented

Hi, I probably encountered a problem in generating HDR gain maps for Apple: I'm not a programmer, just a computer and photography enthusiast. First, I'll describe how I'm using your tool.

Initially, probably because I'm not a programmer, I couldn't find a way to generate an HDR gain map from various ProRaw files recently made with my iPhone 15 Pro Max. So I "unpacked" your Swift code into two files so that in one there is only the "generation" mechanism (to obtain the gain map in PNG format from the DNG file) and in one the original script (to obtain the final file from PNG map and SDR image version in HEIC): in this (clumsy and inconvenient) way, running one script at a time, I manage to generate many files that work beautifully.

If I took a DNG photo with my iPhone in portrait orientation, Lightroom's DNG and HEIC file works perfectly, and the Exif data reports both 90° CW and 270 rotation orientation. Unfortunately, the PNG gain map is made in a different orientation, something "90 degrees counterclockwise" compared to the actual photo.

Those are very good questions and indeed not supported at the current stage. I have some ideas on how to change the code but need to do some exploration. Meanwhile you can try out this app in beta testing: https://testflight.apple.com/join/AtFppKIy. It's essentially a GUI for the script, which allows you to do the processing on an iPhone/iPad. Hopefully that can help you get around the orientation issue. It's still in beta testing and I plan to submit it to App Store in the near future.

Meanwhile you can try out this app in beta testing: testflight.apple.com/join/AtFppKIy

This is awesome! I just joined. Should this work for getting lightroom mobile-exported JPGs with gain maps to render with proper HDR in the Photos app on my iPhone? I can't seem to figure out the correct workflow for that.

@swrobel Thank you. I'm currently working on a video to explain how it works, but I can provide a brief introduction here. The tool has two modes: simple and advanced. In simple mode, you only need to specify an SDR image and click "process." The tool uses a simple algorithm to infer what the HDR version might look like and outputs an HDR image to your photo album.

For more control over the HDR result, you can use advanced mode, which allows for two types of input. Firstly, you can specify an SDR image and then an HDR image. The HDR image must be a JPEG with a gain map. While I haven't tested this with Lightroom due to not having a subscription, I found that it works well with the JPEG file with a gain map generated by Photomater. This method gives you more control over the final HDR appearance. The output will be two images: one is the gain map, and the other is the HDR image.

Alternatively, if you're not satisfied with the HDR output, you can edit the gain map directly and use it as input in advanced mode. You start by providing an SDR image, and then, instead of an HDR image, you supply the edited gain map. The tool will then apply the gain map to the SDR image, replicating what the script is designed to do.

I hope this introduction is helpful. Feel free to reply if you have any more questions.

@grapeot thanks! I'm happy to provide lightroom images if that would be helpful. I have a subscription (although it's worth noting that I believe they offer a trial if you want to try yourself)

@swrobel Thank you! I suggest to first try out the HDR jpg file from Lightroom by following the instructions above. Because although I didn't test Lightroom per se, I checked against Adobe's documentation and their sample images to on the compatibility, and am optimistic that it should be supported. If you still have issues, feel free to attach a sample image with what kind of error message you see and how to reproduce it, and I can help take a closer look. Thanks and happy holidays!

hi guys! any update for the orientation issue? when i try to extarct the GainMap from a photo (input.DNG) taken by iPhone15 pro in portrait orientation, the output GainMap.png is in the 90 degrees counterclockwise compare input photo.
image
image

i have try to change the orientation of the photo (GainMap.png and SDR photo base.jpg make by the input.DNG) manually, then take the second step to merge them into a HDR format JPEG (hdr.jpg), but neither of the manipulation figure this orientation issue. when i use the Adobe Demo app to open the hdr.jpg, the GainMap would still be in 90 degrees counterclockwise compare to the base image base.img
image

commented

Thanks again for all the comments and discussions. I took a closer look at the reported issue and I think technically this is not an issue of the provided script, but rather in the usage of the script. More specifically, when feeding in the gain map image, it is important to ensure that it has the same orientation as the base image.

Below is an example function to load an image with orientation considered. I didn't really test it from end-to-end, but let me know if it still doesn't work. I can try to write an end-to-end example on how to load an orientation corrected image from an iOS DNG file and make it an iOS compatible HDR image in this case.

func cgImageFromUrlWithOrientationCorrected(from url: URL) -> CGImage? {
    guard let source = CGImageSourceCreateWithURL(url as CFURL, nil) else {
        print("Error: Unable to create image source.")
        return nil
    }
    
    let options: [CFString: Any] = [
        kCGImageSourceShouldCache: false,
        kCGImageSourceShouldAllowFloat: true,
        kCGImageSourceCreateThumbnailFromImageIfAbsent: true,
        kCGImageSourceCreateThumbnailWithTransform: true,
        kCGImageSourceThumbnailMaxPixelSize: 20000 // Set this to a large value to get full-size image
    ]
    
    guard let cgImage = CGImageSourceCreateThumbnailAtIndex(source, 0, options as CFDictionary) else {
        print("Error: Unable to create CGImage from source.")
        return nil
    }
    
    return cgImage
}

How to use: replace this block with something like:

    // Load the gain map image
    let gainMapURL = URL(fileURLWithPath: gainMapPath)
    guard let gainMapImage = cgImageFromUrlWithOrientationCorrected(from: gainMapURL) else {
        print("Error loading gain map image.")
        return
    }

If you still cannot get it working, please paste the code you used and I can take another look.