I am exporting a scene to OpenEXR multichannel (with no compression and FULL format) and read it back using Python. Here is the code
exrFile = OpenEXR.InputFile('fallroad_0001.exr')
header = exrFile.header()
dw = header['dataWindow']
pt = Imath.PixelType(Imath.PixelType.FLOAT)
size = (dw.max.x - dw.min.x + 1, dw.max.y - dw.min.y + 1)
cc_r = np.fromstring(exrFile.channel('RenderLayer.Combined.R', pt), dtype=np.float32)
cc_g = np.fromstring(exrFile.channel('RenderLayer.Combined.G', pt), dtype=np.float32)
cc_b = np.fromstring(exrFile.channel('RenderLayer.Combined.B', pt), dtype=np.float32)
cc_r.shape = cc_g.shape = cc_b.shape = (size[1], size[0])
cc = np.dstack((cc_r, cc_g, cc_b))
I understand that an OpenEXR file contain a 'raw' value of the pixel (in high dynamic range), so the pixel values are not in the image standard range [0, 1]. Indeed, here is the range of each channel
[(0.0, 270.6739501953125), (0.0, 221.4493865966797), (0.0, 106.66129302978516)]
Now I am having problems to convert it to the image that Render shows (and export as png), which ranges in [0, 255] or [0, 1]. Scaling [min, max] to [0, 1] or cut off at 1 (values that are greater than 1 become 1) does not work.
I include here the images that I have hand-on. From left to right: image with raw exported float values, image with value cut-off at 1 (all > 1 become 1) and image rendered by Blender