KhronosGroup / KhronosGroup/glTF

Incorrect Color Space Conversion When Exporting Images from OpenEXR to PNG

Open
#2,295 1 comment 0 reactions 0 assignees View on GitHub
Dominant language
HTML
Stars
7.8k
Forks
1.2k
Avg merge
17h 26m
Merged PRs (30d)
5

Description

When converting images from OpenEXR to PNG using the `ExportImage` class, the resulting PNG images appear darker than the original OpenEXR images. This issue seems to stem from a discrepancy in the color spaces used by the two image formats. OpenEXR images use a linear color space, while PNG images use a gamma-corrected color space.

The current implementation of the `ExportImage` class does not appear to account for this difference in color spaces. When creating a new image with `bpy.data.images.new` and setting its pixels with `tmp_image.pixels.foreach_set(pixels)`, the pixel data is assumed to be in the correct color space for the image format. However, if the pixel data is in a linear color space (as it would be for an OpenEXR image), and a PNG image is being created (which uses a gamma-corrected color space), the resulting image will appear darker than expected.

To resolve this issue, a gamma correction should be applied to the pixel data before setting it on the new image. This can be achieved with the following code:

```python
gamma = 2.2
pixels = np.power(pixels, 1 / gamma)
```

This code raises each pixel value to the power of `1 / gamma`, effectively applying a gamma correction to the pixel data. The value of `gamma` is typically `2.2` for sRGB images, which is the color space used by PNG images.

Please note that this is solution is specific to typical PNG color space and the actual process of color space conversion may be more complex than my expertise, depending on the specific color profiles of the images involved. You may need to implement a more comprehensive color space conversion process to ensure accurate results for all image conversions. However, blender has some built in modules for saving images in new formats from raw pixel data. You may be able to leverage that.

**Expected result:**

The PNG image should have the same brightness and color as the original OpenEXR image as shown below.
![image](https://github.com/KhronosGroup/glTF/assets/10996763/84432d3b-fd2b-4238-94f1-3738400b25b8)

**Actual result:**

The PNG image appears darker than the original OpenEXR image.
![image](https://github.com/KhronosGroup/glTF/assets/10996763/3675c7f7-53cb-4efc-90f0-f8f163508cf3)

Contributor guide

Open the contributing guide

Research direction

Start by locating the ExportImage class and the path that creates bpy.data.images.new before calling tmp_image.pixels.foreach_set(pixels). Compare how OpenEXR and PNG color spaces are handled, including Blender's built-in image-saving or conversion support; done means exported PNGs retain the source image's brightness and color.

Written by the indexing model from the issue text.

Assessment

Tech stack
python
Domain
computer-graphics
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.