Skip to content

Commit

Permalink
readme.4
Browse files Browse the repository at this point in the history
Signed-off-by: Cary Phillips <[email protected]>
  • Loading branch information
cary-ilm committed Jul 25, 2024
1 parent c699276 commit c5ee4b9
Showing 1 changed file with 123 additions and 20 deletions.
143 changes: 123 additions & 20 deletions src/wrappers/python/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -72,26 +72,129 @@ The "Hello, World" image writer:
height, width = (20, 10)
RGB = np.random.rand(height, width, 3).astype('f')

import OpenEXR, Imath
from array import array

width = 10
height = 10
size = width * height

h = OpenEXR.Header(width,height)
h['channels'] = {'R' : Imath.Channel(Imath.PixelType(Imath.PixelType.FLOAT)),
'G' : Imath.Channel(Imath.PixelType(Imath.PixelType.FLOAT)),
'B' : Imath.Channel(Imath.PixelType(Imath.PixelType.FLOAT)),
'A' : Imath.Channel(Imath.PixelType(Imath.PixelType.FLOAT))}
o = OpenEXR.OutputFile("hello.exr", h)
r = array('f', [n for n in range(size*0,size*1)]).tobytes()
g = array('f', [n for n in range(size*1,size*2)]).tobytes()
b = array('f', [n for n in range(size*2,size*3)]).tobytes()
a = array('f', [n for n in range(size*3,size*4)]).tobytes()
channels = {'R' : r, 'G' : g, 'B' : b, 'A' : a}
o.writePixels(channels)
o.close()
channels = { "RGB" : RGB }
header = { "compression" : OpenEXR.ZIP_COMPRESSION,
"type" : OpenEXR.scanlineimage }

with OpenEXR.File(header, channels) as outfile:
outfile.write("readme.exr")

Or alternatively, construct the same output file via separate pixel arrays
for each channel:

# Generate arrays for R, G, and B channels with random values
height, width = (20, 10)
R = np.random.rand(height, width).astype('f')
G = np.random.rand(height, width).astype('f')
B = np.random.rand(height, width).astype('f')
channels = { "R" : R, "G" : G, "B" : B }
header = { "compression" : OpenEXR.ZIP_COMPRESSION,
"type" : OpenEXR.scanlineimage }

with OpenEXR.File(header, channels) as outfile:
outfile.write("readme.exr")

The corresponding example of reading an image is:

with OpenEXR.File("readme.exr") as infile:

RGB = infile.channels()["RGB"].pixels
height, width, _ = RGB.shape
for y in range(height):
for x in range(width):
pixel = tuple(RGB[y, x])
print(f"pixel[{y}][{x}]={pixel}")

Or alternatively, read the data as separate arrays for each channel:

with OpenEXR.File("readme.exr", separate_channels=True) as infile:

header = infile.header()
print(f"type={header['type']}")
print(f"compression={header['compression']}")

R = infile.channels()["R"].pixels
G = infile.channels()["G"].pixels
B = infile.channels()["B"].pixels
height, width = R.shape
for y in range(height):
for x in range(width):
pixel = (R[y, x], G[y, x], B[y, x])
print(f"pixel[{y}][{x}]={pixel}")

To modify the header metadata in a file:

with OpenEXR.File("readme.exr") as f:
f.header()["displayWindow"] = ((3,4),(5,6))
f.header()["screenWindowCenter"] = np.array([1.0,2.0],'float32')
f.header()["comments"] = "test image"
f.header()["longitude"] = -122.5
f.write("readme_modified.exr")

with OpenEXR.File("readme_modified.exr") as o:
dw = o.header()["displayWindow"]
assert (tuple(dw[0]), tuple(dw[1])) == ((3,4),(5,6))
swc = o.header()["screenWindowCenter"]
assert tuple(swc) == (1.0, 2.0)
assert o.header()["comments"] == "test image"
assert o.header()["longitude"] == -122.5

Note that OpenEXR's Imath-based vector and matrix attribute values
appear in the header dictionary as 2-element, 3-element, 3x3, 4x4
numpy arrays, and bounding boxes appear as tuples of 2-element arrays,
or tuples for convenience.

To read and write a multi-part file, use a list of ``Part`` objects:

height, width = (20, 10)
Z0 = np.zeros((height, width), dtype='f')
Z1 = np.ones((height, width), dtype='f')

P0 = OpenEXR.Part({}, {"Z" : Z0 })
P1 = OpenEXR.Part({}, {"Z" : Z1 })

f = OpenEXR.File([P0, P1])
f.write("readme_2part.exr")

with OpenEXR.File("readme_2part.exr") as o:
assert o.parts[0].name() == "Part0"
assert o.parts[0].width() == 10
assert o.parts[0].height() == 20
assert o.parts[1].name() == "Part1"
assert o.parts[1].width() == 10
assert o.parts[1].height() == 20

Deep data is stored in a numpy array whose entries are numpy
arrays. Construct a numpy array with a ``dtype`` of ``object``, and
assign each entry a numpy array holding the samples. Each pixel can
have a different number of samples, including ``None`` for no data,
but all channels in a given part must have the same number of samples.

height, width = (20, 10)

Z = np.empty((height, width), dtype=object)
for y in range(height):
for x in range(width):
Z[y, x] = np.array([y*width+x], dtype='uint32')

channels = { "Z" : Z }
header = { "compression" : OpenEXR.ZIPS_COMPRESSION,
"type" : OpenEXR.deepscanline }
with OpenEXR.File(header, channels) as outfile:
outfile.write("readme_test_tiled_deep.exr")

To read a deep file:

with OpenEXR.File("readme_test_tiled_deep.exr") as infile:

Z = infile.channels()["Z"].pixels
height, width = Z.shape
for y in range(height):
for x in range(width):
for z in Z[y,x]:
print(f"deep sample at {y},{x}: {z}")


# Community

Expand Down

0 comments on commit c5ee4b9

Please sign in to comment.