{"id":5349,"library":"openexr","title":"OpenEXR Python Bindings","description":"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.","status":"active","version":"3.4.9","language":"en","source_language":"en","source_url":"https://github.com/AcademySoftwareFoundation/OpenEXR","tags":["image processing","computer graphics","exr","hdr","bindings","vfx"],"install":[{"cmd":"pip install openexr","lang":"bash","label":"Install stable version"}],"dependencies":[{"reason":"Essential for efficient handling of image pixel data (arrays).","package":"numpy","optional":false},{"reason":"Provides Python bindings for Imath (vector/matrix math library), commonly used alongside OpenEXR for geometric data in headers.","package":"imath","optional":true}],"imports":[{"symbol":"openexr","correct":"import openexr"},{"note":"Imath is a separate, but closely related, package. While OpenEXR provides its core functionality, Imath types are best accessed from the dedicated 'imath' package.","wrong":"from openexr import Imath","symbol":"Imath","correct":"import Imath"}],"quickstart":{"code":"import openexr\nimport Imath\nimport numpy as np\n\n# Define image properties\nwidth = 256\nheight = 256\nhalf_channels = {'R': Imath.ChannelList().add('R', Imath.PixelType(Imath.PixelType.HALF)),\n                 'G': Imath.ChannelList().add('G', Imath.PixelType(Imath.PixelType.HALF)),\n                 'B': Imath.ChannelList().add('B', Imath.PixelType(Imath.PixelType.HALF))}\n\n# Create some dummy data (e.g., a simple gradient)\nx = np.linspace(0, 1, width)\ny = np.linspace(0, 1, height)\nR = np.outer(y, x).astype(np.float16)\nG = np.outer(y, 1-x).astype(np.float16)\nB = np.outer(1-y, x).astype(np.float16)\n\n# Write an EXR file\noutput_filename = 'example.exr'\nheader = openexr.Header(width, height)\n# Ensure correct channel types and data window if writing half data\n# header['channels'] = half_channels \n# The above is for explicit channel list. For simplicity, let's use default half for RGB.\n\nfile_out = openexr.OutputFile(output_filename, header)\nfile_out.writePixels({'R': R.tobytes(), 'G': G.tobytes(), 'B': B.tobytes()})\nfile_out.close()\nprint(f\"Written {output_filename}\")\n\n# Read the EXR file\nfile_in = openexr.InputFile(output_filename)\nheader_in = file_in.header()\ndata_window = header_in['dataWindow']\ndw = Imath.Box2i(data_window)\nsize = (dw.max.x - dw.min.x + 1, dw.max.y - dw.min.y + 1)\n\n# Read 'R' channel data as bytes and convert to numpy array\nr_channel_bytes = file_in.channel('R', Imath.PixelType(Imath.PixelType.HALF))\nr_data = np.frombuffer(r_channel_bytes, dtype=np.float16).reshape(size[1], size[0])\n\nprint(f\"Read R channel data shape: {r_data.shape}\")\nprint(f\"First few R values: {r_data.flatten()[:5]}\")\nfile_in.close()\n","lang":"python","description":"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`)."},"warnings":[{"fix":"Rewrite code to use the new `openexr` API (e.g., `openexr.InputFile` instead of `OpenEXR.InputFile`). Ensure `pip install openexr` and potentially `pip install imath` are used, not `pip install PyOpenEXR PyImath`.","message":"The `openexr` package is the official Python 3 binding for OpenEXR 3.x, replacing the older `PyOpenEXR` and `PyImath` packages which were tied to OpenEXR 2.x. Users migrating from older setups will find significant API differences and different import paths. Do not mix `openexr` with `PyOpenEXR`.","severity":"breaking","affected_versions":"< 3.0"},{"fix":"Prioritize `pip install openexr` to leverage pre-built wheels. If building from source, ensure `cmake` and all necessary C++ development headers for OpenEXR and its dependencies are installed on your system.","message":"Installing `openexr` from source can be complex due to its underlying C++ dependencies (OpenEXR, Imath, zlib, etc.). Pre-built wheels are typically available on PyPI for common platforms, but if a wheel isn't available for your specific Python version/OS, a robust C++ build environment (including `cmake`) is required.","severity":"gotcha","affected_versions":"All versions (when building from source)"},{"fix":"Always `import Imath` separately if you need to create or manipulate Imath-specific types (e.g., `Imath.V3f`, `Imath.Box2i`) in your Python code, and ensure the `imath` package is installed (`pip install imath`).","message":"While `openexr` provides EXR file I/O, `Imath` (vectors, matrices, boxes) is typically accessed via the separate `imath` Python package. Though `openexr`'s internal C++ libraries use Imath, its Python bindings do not fully expose all Imath types directly under the `openexr` namespace.","severity":"gotcha","affected_versions":"All versions"},{"fix":"When reading, use `np.frombuffer(raw_bytes, dtype=...).reshape(...)`. When writing, convert your `numpy` arrays to bytes using `array.tobytes()` and ensure the `PixelType` in the `openexr.Header` matches your data's `dtype`.","message":"Pixel data read from `openexr` channels are returned as raw `bytes` objects. These must be converted to `numpy.ndarray` for practical manipulation, requiring careful handling of `dtype` (e.g., `np.float16` for `HALF`, `np.float32` for `FLOAT`) and `reshape` to the correct image dimensions.","severity":"gotcha","affected_versions":"All versions"},{"fix":"Always keep your `openexr` installation updated to the latest patch release (e.g., `pip install --upgrade openexr`) to mitigate known security risks, especially when dealing with EXR files from untrusted sources.","message":"Multiple recent patch releases (e.g., 3.4.9, 3.3.9, 3.2.7) have addressed significant security vulnerabilities, including heap out-of-bounds writes and integer overflows, which could lead to crashes or arbitrary code execution when processing malformed EXR files.","severity":"gotcha","affected_versions":"< 3.4.9, < 3.3.9, < 3.2.7"}],"env_vars":null,"last_verified":"2026-04-13T00:00:00.000Z","next_check":"2026-07-12T00:00:00.000Z"}