import os import subprocess import numpy as np from scipy import misc as scipy_io __version__ = "0.5" try: import ezexr except ImportError as e: print("Could not import exr module:", e) try: import imageio imsave_ldr = imageio.imwrite except ImportError as e: imsave_ldr = scipy_io.imsave print("Could not import hdr module:", e) def imwrite(data, filename): _, ext = os.path.splitext(filename.lower()) if ext == '.exr': ezexr.imwrite(filename, data) elif ext in ['.hdr', '.pic']: _hdr_write(filename, data) else: imsave_ldr(filename, np.clip(255.*data, 0, 255).astype('uint8')) def imsave(filename, data): imwrite(data, filename) def imread(filename, format_="float32"): """Reads an image. Supports exr, hdr, cr2, tiff, jpg, png and everything SciPy/PIL supports. :filename: file path. :format_: format in which to return the value. If set to "native", the native format of the file will be given (e.g. uint8 for jpg). """ ldr = False _, ext = os.path.splitext(filename.lower()) if ext == '.exr': im = ezexr.imread(filename) elif ext in ['.hdr', '.pic']: im = _hdr_read(filename) elif ext in ['.cr2', '.nef', '.raw']: im = _raw_read(filename) elif ext in ['.tiff', '.tif']: try: import tifffile as tiff except ImportError: print('Install tifffile for better tiff support. Fallbacking to ' 'scipy.') im = scipy_io.imread(filename) else: im = tiff.imread(filename) else: im = scipy_io.imread(filename) ldr = True if format_ == "native": return im elif ldr and not 'int' in format_: return im.astype(format_) / 255. else: return im.astype(format_) def _raw_read(filename): """Calls the dcraw program to unmosaic the raw image.""" fn, _ = os.path.splitext(filename.lower()) target_file = "{}.tiff".format(fn) if not os.path.exists(target_file): ret = subprocess.call('dcraw -v -T -4 -t 0 -j {}'.format(filename)) if ret != 0: raise Exception('Could not execute dcraw. Make sure the executable' ' is available.') try: import tifffile as tiff except ImportError: raise Exception('Install tifffile to read the converted tiff file.') else: return tiff.imread(target_file) def _hdr_write(filename, data, **kwargs): """Write a Radiance hdr file. Refer to the ImageIO API ( http://imageio.readthedocs.io/en/latest/userapi.html ) for parameter description.""" imageio.imwrite(filename, data, **kwargs) def _hdr_read(filename, use_imageio=False): """Read hdr file. .. TODO: * Support axis other than -Y +X """ if use_imageio: return imageio.imread(filename, **kwargs) with open(filename, "rb") as f: MAGIC = f.readline().strip() assert MAGIC == b'#?RADIANCE', "Wrong header found in {}".format(filename) comments = b"" while comments[:6] != b"FORMAT": comments = f.readline().strip() assert comments[:3] != b"-Y ", "Could not find data format" assert comments == b'FORMAT=32-bit_rle_rgbe', "Format not supported" while comments[:3] != b"-Y ": comments = f.readline().strip() _, height, _, width = comments.decode("ascii").split(" ") height, width = int(height), int(width) rgbe = np.fromfile(f, dtype=np.uint8).reshape((height, width, 4)) rgb = np.empty((height, width, 3), dtype=np.float) rgb[...,0] = np.ldexp(rgbe[...,0], rgbe[...,3].astype('int') - 128) rgb[...,1] = np.ldexp(rgbe[...,1], rgbe[...,3].astype('int') - 128) rgb[...,2] = np.ldexp(rgbe[...,2], rgbe[...,3].astype('int') - 128) # TODO: This will rescale all the values to be in [0, 1]. Find a way to retrieve the original values. rgb /= rgb.max() return rgb __all__ = ['imwrite', 'imsave', 'imread']