Last active
March 22, 2024 13:10
-
-
Save arseniy-panfilov/4dc8fc5131277affe64619b1a9d00da0 to your computer and use it in GitHub Desktop.
Convert .EXR image to pillow's `Image` with gamma encoding
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from PIL import Image | |
import OpenEXR | |
import Imath | |
import numpy | |
import numexpr as ne | |
FLOAT = Imath.PixelType(Imath.PixelType.FLOAT) | |
def exr_to_array(exrfile): | |
file = OpenEXR.InputFile(exrfile) | |
dw = file.header()['dataWindow'] | |
channels = list(file.header()['channels'].keys()) | |
channels_list = [c for c in ('R', 'G', 'B', 'A') if c in channels] | |
size = (dw.max.x - dw.min.x + 1, dw.max.y - dw.min.y + 1) | |
color_channels = file.channels(channels_list, FLOAT) | |
channels_tuple = [numpy.frombuffer(channel, dtype='f') for channel in color_channels] | |
return numpy.dstack(channels_tuple).reshape(size + (len(channels_tuple),)) | |
def encode_to_srgb(x): | |
a = 0.055 | |
return ne.evaluate("""where( | |
x <= 0.0031308, | |
x * 12.92, | |
(1 + a) * (x ** (1 / 2.4)) - a | |
)""") | |
def exr_to_srgb(exrfile): | |
array = exr_to_array(exrfile) | |
result = encode_to_srgb(array) * 255. | |
present_channels = ["R", "G", "B", "A"][:result.shape[2]] | |
channels = "".join(present_channels) | |
return Image.fromarray(result.astype('uint8'), channels) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment