OpenEXR Python Bindings

3.4.9 · active · verified Mon Apr 13

The `openexr` library provides official Python bindings for the OpenEXR image file format, a high-dynamic-range (HDR) image file format used in computer graphics and visual effects. It allows Python applications to read, write, and manipulate EXR files, including multi-part, multi-channel, and deep images. The library is actively maintained with frequent patch releases addressing security vulnerabilities and bug fixes, typically following the major C++ OpenEXR library releases.

Warnings

Install

Imports

Quickstart

This quickstart demonstrates writing a simple RGB image with `HALF` precision to an EXR file and then reading the red channel back. It utilizes `numpy` for data manipulation, which is standard practice when working with image pixel data in `openexr`. Ensure you have `numpy` and `imath` installed (`pip install numpy imath`).

import openexr
import Imath
import numpy as np

# Define image properties
width = 256
height = 256
half_channels = {'R': Imath.ChannelList().add('R', Imath.PixelType(Imath.PixelType.HALF)),
                 'G': Imath.ChannelList().add('G', Imath.PixelType(Imath.PixelType.HALF)),
                 'B': Imath.ChannelList().add('B', Imath.PixelType(Imath.PixelType.HALF))}

# Create some dummy data (e.g., a simple gradient)
x = np.linspace(0, 1, width)
y = np.linspace(0, 1, height)
R = np.outer(y, x).astype(np.float16)
G = np.outer(y, 1-x).astype(np.float16)
B = np.outer(1-y, x).astype(np.float16)

# Write an EXR file
output_filename = 'example.exr'
header = openexr.Header(width, height)
# Ensure correct channel types and data window if writing half data
# header['channels'] = half_channels 
# The above is for explicit channel list. For simplicity, let's use default half for RGB.

file_out = openexr.OutputFile(output_filename, header)
file_out.writePixels({'R': R.tobytes(), 'G': G.tobytes(), 'B': B.tobytes()})
file_out.close()
print(f"Written {output_filename}")

# Read the EXR file
file_in = openexr.InputFile(output_filename)
header_in = file_in.header()
data_window = header_in['dataWindow']
dw = Imath.Box2i(data_window)
size = (dw.max.x - dw.min.x + 1, dw.max.y - dw.min.y + 1)

# Read 'R' channel data as bytes and convert to numpy array
r_channel_bytes = file_in.channel('R', Imath.PixelType(Imath.PixelType.HALF))
r_data = np.frombuffer(r_channel_bytes, dtype=np.float16).reshape(size[1], size[0])

print(f"Read R channel data shape: {r_data.shape}")
print(f"First few R values: {r_data.flatten()[:5]}")
file_in.close()

view raw JSON →