Edit Ultra HDR images

The Ultra HDR image format encodes luminosity information that lets devices display brighter images with more intense colors. When your app edits an Ultra HDR image, you want to make sure to preserve that luminosity information. This is important even if the user's device doesn't support displaying an Ultra HDR image at full intensity. After all, the user might share their image to someone with a device that supports Ultra HDR, or they might save that image and look at it again on a new device years later.

The good news is most Android methods for editing bitmaps support the Ultra HDR image format. If you're making basic edits to an image, like cropping or rotating it, the standard Android methods do the job—you'll end up with an ultra HDR image with the new dimensions or orientation.

The job is trickier if you're modifying the contents of the image. In those cases, the standard editing methods preserve the luminosity information of the old image, which might not be what you want. In those cases, you might need to edit or remove the gain map (which encodes the image's luminosity information) to get the right result.

Ultra HDR format overview

The Ultra HDR image format is described in detail in the Ultra HDR Image specification. The most important thing to understand is an Ultra HDR image contains both a primary image and a gain map.

  • The primary image has the color information for each pixel of the image.
  • The gain map is a standard JPEG image with the same proportions as the primary image, though not necessarily the same pixel dimensions. Each pixel of the gain map specifies the luminance of the corresponding part of the primary image.

The gain map can be either grayscale or color. If the gain map is in color, each color channel on the gain map specifies the luminance of that color channel on the corresponding part of the primary image. If the gain map is grayscale, each pixel of the gain map specifies the luminance of all three color channels on that portion of the primary image.

The gain map must have the same proportions as the primary image, but it does not have to have the same pixel dimensions. In fact, when the Android platform creates Ultra HDR images, it creates a gain map with a smaller width and height than the primary image; doing so makes the file size significantly smaller, but still encodes enough information for a good result. This means that each pixel in the gain map might store the luminance information for several pixels in the primary image.

Basic Ultra HDR edits

If you use the Android Bitmap APIs to make basic transformations to an Ultra HDR image, the methods make the appropriate changes to the gain map. The following Bitmap operations are supported:

  • Rotate: If you rotate an Ultra HDR image, the method rotates the gain map too.
  • Crop: If you crop an Ultra HDR image, the method crops the gain map appropriately.
  • Scale: If you scale an Ultra HDR image, the method scales the gain map so it has half the width and half the height of the resized primary image.

In each case, the luminosity information is preserved.

Advanced Ultra HDR edits

If you make more elaborate edits to an Ultra HDR image, the gain map is preserved unchanged, which may not give you the results you want.

Common edits that might result in this situation include:

  • Adding stickers or emoji: The added sticker would have the same luminosity and color vividness values as the area it was pasted on.
  • Overlaying a second image: The new image would use the luminosity and color vividness information of the content it's overlaying.
  • Adding filters: The old gain map's information might not be appropriate for the modified primary image.

In each case, the old luminosity and color vividness information is preserved, but it might not be appropriate for the modified image.

If the original gain map is appropriate for the edited image, you don't have to do anything. If you do want to modify the gain map, the usual workflow is:

  1. Fetch the image's current gain map by calling Bitmap.getGainmap() and cache it.
  2. Modify the primary image as desired.
  3. Make corresponding edits to the cached gain map. For example, if you pasted an emoji onto the primary image, you might set the corresponding portion of the gain map to a neutral value, like Color.GRAY.

  4. Apply the modified gain map back to the image by calling Bitmap.setGainmap().

Additional resources

To learn more about Ultra HDR images, see the following additional resources: