OpenEXR bindings for Python

Download OpenEXR-0.0.4.tar.gz

OpenEXR is an image format developed by ILM. Its main advantage is higher dynamic range: it supports floating point pixels.

This small module adds Python bindings for the OpenEXR libraries: you can now read and write OpenEXR files from Python. Note that this module only loads and stores images: it does not do any image manipulation operations. For that you might want to use one of:

Here's a brief sample that duplicates exrnormalize from exrtools.


import sys
import OpenEXR
import Image
from Imath import *

if len(sys.argv) != 3:
    print "usage: exrnormalize.py exr-input-file exr-output-file"
    sys.exit(1)

# Open the input file
file = OpenEXR.InputFile(sys.argv[1])

# Compute the size
dw = file.header()['dataWindow']
sz = (dw.max.x - dw.min.x + 1, dw.max.y - dw.min.y + 1)

# Read the three color channels as monochrome float format images
(R,G,B) = [Image.fromstring("F", sz, file.channel(Chan)) for Chan in "RGB"]
file.close()

# Normalize so that brightest sample is 1
hi = max([Chan.getextrema()[1] for Chan in [R,G,B]])
(R,G,B) = [Chan.point(lambda i: i * (1. / hi) + 0.0) for Chan in [R,G,B]]

# Convert the three images into strings
(R,G,B) = [Chan.tostring() for Chan in [R,G,B]]

# Write the three color channels to the output file
out = OpenEXR.OutputFile(sys.argv[2], OpenEXR.Header(sz[0], sz[1]))
out.writePixels({'R':R, 'G':G, 'B':B})
out.close()


Change log

OpenEXR-0.0.4

OpenEXR-0.0.3

OpenEXR-0.0.1

Module Contents

InputFile(filename)
Open the specified OpenEXR format file for reading, and return an InputFile object.
OutputFile(filename, header)
Open the specified OpenEXR format file for writing, with the specified header, and return an OutputFile object.
Header(xsize, ysize)
Return a default OpenEXR header for an image of the specified size. The header is for an RGB image, with each channel in FLOAT.
FLOAT
32-bit floating point type
HALF
16-bit floating point type
UINT
32-bit unsigned integer type

InputFile Objects

InputFile objects support the following methods:

header()
Return the header of the open file. The header is a dictionary as described below.
channel(channel, [pixeltype, [miny ,maxy]])
Read a channel from the OpenEXR image. Channel is a string selecting the channel of the image. This method returns the channel's data in the format specified by pixeltype (see Imath.PixelType), or Imath.PixelType(OpenEXR.FLOAT) by default. If miny and maxy are not supplied, then the method reads the entire image. Note that this method returns the channel as a Python string: the caller must then convert it to the appropriate format as necessary.
close()
Close the open file.

OutputFile Objects

OutputFile objects support the following methods:

header()
Return the header of the open file. The header is a dictionary as described below.
writePixels(dict, [scanlines])
Write the specified channels to the OpenEXR image. dict specifies multiple channels. If scanlines is not specified, then the entire image is assumed. dict specifies each channel's data as channel:data, where channel and data are both strings. This method uses the header (specified when the file was opened) to determine the format of the data (FLOAT, HALF or UNIT) for each channel. If the string data is not of the appropriate size, this method raises an exception.
close()
Close the open file. Calling this method is MANDANTORY, otherwise the file will be incomplete.

OpenEXR Header as dictionary

This module represents OpenEXR headers as regular Python dictionaries. In this dictionary the keys are strings, and the values are such that the module can determine their type. The module Imath provides the classes for attribute types.

>>> import Imath
>>> import OpenEXR
>>> print OpenEXR.InputFile("GoldenGate.exr").header()
{'capDate': '2004:01:04 18:10:00',
'compression': PIZ_COMPRESSION,
'latitude': 37.827701568603516,
'pixelAspectRatio': 1.0,
'altitude': 274.5,
'displayWindow': (0, 0) - (1261, 859),
'focus': inf,
'comments': 'View from Hawk Hill towards San Francisco',
'screenWindowWidth': 1.1499999761581421,
'channels': {'R': HALF (1, 1), 'B': HALF (1, 1), 'G': HALF (1, 1)},
'isoSpeed': 50.0,
'utcOffset': 28800.0,
'longitude': -122.49960327148438,
'dataWindow': (0, 0) - (1261, 859),
'screenWindowCenter': (0.0, 0.0),
'aperture': 2.7999999523162842,
'preview': <Imath.PreviewImage instance at 0x81b8c6c>
'owner': 'Copyright 2004 Industrial Light & Magic',
'expTime': 8.0,
'lineOrder': INCREASING_Y}


A value may be:

string
header['owner'] = 'Copyright 2007 James Bowman'

float
header['isoSpeed'] = 50.0

int
header['version'] = 1001

dict
A dict represents the image's channels. In the dict, the keys are the channel names, and the values are of class Imath.Channel.
header['channels'] = { 'L' : Imath.Channel(PixelType(OpenEXR.HALF)), 'Z' : Imath.Channel(PixelType(OpenEXR.FLOAT))}

Imath.Box2i
header['dataWindow'] = Imath.Box2i(Imath.point(0,0), Imath.point(640,480))

Imath.Box2f
header['regionOfInterest'] = Imath.Box2f(Imath.point(75.0,75.0), Imath.point(100.0,100.0))

Imath.V2f
header['originMarker'] = Imath.point(0.378, 0.878)

Imath.LineOrder
header['lineOrder'] = Imath.LineOrder(Imath.LineOrder.INCREASING_Y)

Imath.PreviewImage
A preview image, specified by height, width, and a string of length 4*width*height. The pixels are in RGBA order.
header['preview'] = Imath.PreviewImage(320,200,pixels)
or even:
import Image
im = ...
header['preview'] = Imath.PreviewImage(im.size[0], im.size[1], im.convert("RGBA").tostring())

Imath.Compression
header['Compression'] = Imath.Compression(Imath.Compression.PIZ_COMPRESSION)

Not Yet Implemented

I have yet to implement various OpenEXR features - so if you want something in particular, email me and I will try to get it done.