def write_image(cls, file: Path, pixels: np.array): output = ImageOutput.create(file.as_posix()) if not output: LOGGER.error('Error creating oiio image output:\n%s', oiio.geterror()) return if len(pixels.shape) < 3: LOGGER.error( 'Can not create image with Pixel data in this shape. Expecting 3 or 4 channels(RGB, RGBA).' ) return h, w, c = pixels.shape spec = ImageSpec(w, h, c, cls.get_numpy_oiio_img_format(pixels)) result = output.open(file.as_posix(), spec) if result: try: output.write_image(pixels) except Exception as e: LOGGER.error('Could not write Image: %s', e) else: LOGGER.error('Could not open image file for writing: %s: %s', file.name, output.geterror()) output.close()
def write_image(image, path, bit_depth='float32'): """ Writes given image using *OpenImageIO*. Parameters ---------- image : array_like Image data. path : unicode Image path. bit_depth : unicode, optional **{'float32', 'uint8', 'uint16', 'float16'}**, Image bit_depth. Returns ------- bool Definition success. Examples -------- >>> import os >>> path = os.path.join('tests', 'resources', 'CMSTestPattern.exr') >>> image = read_image_as_array(path) # doctest: +SKIP >>> path = os.path.join('tests', 'resources', 'CMSTestPattern.png') >>> write_image(image, path, 'uint8') # doctest: +SKIP True """ if is_openimageio_installed(raise_exception=True): from OpenImageIO import ImageOutput, ImageOutputOpenMode, ImageSpec bit_depth_specification = BIT_DEPTH_MAPPING.get(bit_depth) bit_depth = bit_depth_specification.openimageio image = np.asarray(image) image *= bit_depth_specification.domain if bit_depth_specification.clip: image = np.clip(image, 0, bit_depth_specification.domain) image = image.astype(bit_depth_specification.numpy) if image.ndim == 2: height, width = image.shape channels = 1 else: height, width, channels = image.shape specification = ImageSpec(width, height, channels, bit_depth) image_output = ImageOutput.create(path) image_output.open(path, specification, ImageOutputOpenMode.Create) image_output.write_image(bit_depth, image.tostring()) image_output.close() return True
def write_image(image, path, bit_depth='float32'): """ Writes given image using *OpenImageIO*. Parameters ---------- image : array_like Image data. path : unicode Image path. bit_depth : unicode, optional {'float32', 'uint8', 'uint16', 'float16'} Image bit_depth. Returns ------- bool Definition success. Examples -------- >>> import os >>> path = os.path.join('tests', 'resources', 'CMSTestPattern.exr') >>> image = read_image_as_array(path) # doctest: +SKIP >>> path = os.path.join('tests', 'resources', 'CMSTestPattern.png') >>> write_image(image, path, 'uint8') # doctest: +SKIP True """ if image.ndim != 3: raise ValueError( 'Image must have exactly 3 dimensions!') if is_openimageio_installed(raise_exception=True): from OpenImageIO import ImageOutput, ImageOutputOpenMode, ImageSpec bit_depth_specification = BIT_DEPTH_MAPPING.get(bit_depth) bit_depth = bit_depth_specification.openimageio image = np.asarray(image) image *= bit_depth_specification.domain if bit_depth_specification.clip: image = np.clip(image, 0, bit_depth_specification.domain) image = image.astype(bit_depth_specification.numpy) height, width, channels = image.shape specification = ImageSpec(width, height, channels, bit_depth) image_output = ImageOutput.create(path) image_output.open(path, specification, ImageOutputOpenMode.Create) image_output.write_image(bit_depth, image.tostring()) image_output.close() return True
def write_image(image, path, bit_depth='float32', attributes=None): """ Writes given image using *OpenImageIO*. Parameters ---------- image : array_like Image data. path : unicode Image path. bit_depth : unicode, optional **{'float32', 'uint8', 'uint16', 'float16'}**, Image bit_depth. attributes : array_like, optional An array of :class:`colour.io.ImageAttribute_Specification` class instances used to set attributes of the image. Returns ------- bool Definition success. Examples -------- Basic image writing: >>> import os >>> path = os.path.join('tests', 'resources', 'CMSTestPattern.exr') >>> image = read_image(path) # doctest: +SKIP >>> path = os.path.join('tests', 'resources', 'CMSTestPattern.tif') >>> write_image(image, path) # doctest: +SKIP True Advanced image writing while setting attributes: >>> compression = ImageAttribute_Specification('Compression', 'none') >>> write_image(image, path, 'uint8', [compression]) # doctest: +SKIP True """ if is_openimageio_installed(raise_exception=True): from OpenImageIO import ImageOutput, ImageOutputOpenMode, ImageSpec path = str(path) if attributes is None: attributes = [] bit_depth_specification = BIT_DEPTH_MAPPING[bit_depth] bit_depth = bit_depth_specification.openimageio image = as_float_array(image) image *= bit_depth_specification.domain if bit_depth_specification.clip: image = np.clip(image, 0, bit_depth_specification.domain) image = image.astype(bit_depth_specification.numpy) if image.ndim == 2: height, width = image.shape channels = 1 else: height, width, channels = image.shape specification = ImageSpec(width, height, channels, bit_depth) for attribute in attributes: name = str(attribute.name) value = (str(attribute.value) if isinstance( attribute.value, string_types) else attribute.value) type_ = attribute.type_ if attribute.type_ is None: specification.attribute(name, value) else: specification.attribute(name, type_, value) image_output = ImageOutput.create(path) image_output.open(path, specification, ImageOutputOpenMode.Create) image_output.write_image(bit_depth, image.tostring()) image_output.close() return True
def write_image_OpenImageIO(image, path, bit_depth='float32', attributes=None): """ Writes given image at given path using *OpenImageIO*. Parameters ---------- image : array_like Image data. path : unicode Image path. bit_depth : unicode, optional **{'float32', 'uint8', 'uint16', 'float16'}**, Bit depth to write the image at, the bit depth conversion behaviour is ruled directly by *OpenImageIO*. attributes : array_like, optional An array of :class:`colour.io.ImageAttribute_Specification` class instances used to set attributes of the image. Returns ------- bool Definition success. Examples -------- Basic image writing: >>> import os >>> import colour >>> path = os.path.join(colour.__path__[0], 'io', 'tests', 'resources', ... 'CMS_Test_Pattern.exr') >>> image = read_image(path) # doctest: +SKIP >>> path = os.path.join(colour.__path__[0], 'io', 'tests', 'resources', ... 'CMSTestPattern.tif') >>> write_image(image, path) # doctest: +SKIP True Advanced image writing while setting attributes: >>> compression = ImageAttribute_Specification('Compression', 'none') >>> write_image(image, path, 'uint8', [compression]) # doctest: +SKIP True """ if is_openimageio_installed(raise_exception=True): # pragma: no cover from OpenImageIO import VERSION_MAJOR, ImageOutput, ImageSpec path = str(path) if attributes is None: attributes = [] bit_depth_specification = BIT_DEPTH_MAPPING[bit_depth] bit_depth = bit_depth_specification.openimageio image = as_float_array(image) image = image * bit_depth_specification.domain if bit_depth_specification.clip: image = np.clip(image, 0, bit_depth_specification.domain) image = image.astype(bit_depth_specification.numpy) if image.ndim == 2: height, width = image.shape channels = 1 else: height, width, channels = image.shape specification = ImageSpec(width, height, channels, bit_depth) for attribute in attributes: name = str(attribute.name) value = (str(attribute.value) if isinstance( attribute.value, string_types) else attribute.value) type_ = attribute.type_ if attribute.type_ is None: specification.attribute(name, value) else: specification.attribute(name, type_, value) image_output = ImageOutput.create(path) if VERSION_MAJOR == 1: from OpenImageIO import ImageOutputOpenMode image_output.open(path, specification, ImageOutputOpenMode.Create) image_output.write_image(bit_depth, image.tostring()) else: image_output.open(path, specification) image_output.write_image(image) image_output.close() return True
def write_image_OpenImageIO( image: ArrayLike, path: str, bit_depth: Literal[ "uint8", "uint16", "float16", "float32", "float64", "float128" ] = "float32", attributes: Optional[Sequence] = None, ) -> Boolean: # noqa: D405,D407,D410,D411 """ Write given image at given path using *OpenImageIO*. Parameters ---------- image Image data. path Image path. bit_depth Bit depth to write the image at, the bit depth conversion behaviour is ruled directly by *OpenImageIO*. attributes An array of :class:`colour.io.ImageAttribute_Specification` class instances used to set attributes of the image. Returns ------- :class:`bool` Definition success. Examples -------- Basic image writing: >>> import os >>> import colour >>> path = os.path.join(colour.__path__[0], 'io', 'tests', 'resources', ... 'CMS_Test_Pattern.exr') >>> image = read_image(path) # doctest: +SKIP >>> path = os.path.join(colour.__path__[0], 'io', 'tests', 'resources', ... 'CMSTestPattern.tif') >>> write_image_OpenImageIO(image, path) # doctest: +SKIP True Advanced image writing while setting attributes: >>> compression = ImageAttribute_Specification('Compression', 'none') >>> write_image_OpenImageIO(image, path, 'uint8', [compression]) ... # doctest: +SKIP True Writing an "ACES" compliant "EXR" file: >>> if is_openimageio_installed(): # doctest: +SKIP ... from OpenImageIO import TypeDesc ... chromaticities = ( ... 0.7347, 0.2653, 0.0, 1.0, 0.0001, -0.077, 0.32168, 0.33767) ... attributes = [ ... ImageAttribute_Specification('acesImageContainerFlag', True), ... ImageAttribute_Specification( ... 'chromaticities', chromaticities, TypeDesc('float[8]')), ... ImageAttribute_Specification('compression', 'none')] ... write_image_OpenImageIO(image, path, attributes=attributes) """ from OpenImageIO import ImageOutput, ImageSpec image = as_float_array(image) path = str(path) attributes = cast(List, optional(attributes, [])) bit_depth_specification = MAPPING_BIT_DEPTH[bit_depth] if bit_depth_specification.numpy in [np.uint8, np.uint16]: mininum, maximum = np.iinfo(np.uint8).min, np.iinfo(np.uint8).max image = np.clip(image * maximum, mininum, maximum) image = as_int_array(image, bit_depth_specification.numpy) image = image.astype(bit_depth_specification.numpy) if image.ndim == 2: height, width = image.shape channels = 1 else: height, width, channels = image.shape specification = ImageSpec( width, height, channels, bit_depth_specification.openimageio ) for attribute in attributes: name = str(attribute.name) value = ( str(attribute.value) if isinstance(attribute.value, str) else attribute.value ) type_ = attribute.type_ if attribute.type_ is None: specification.attribute(name, value) else: specification.attribute(name, type_, value) image_output = ImageOutput.create(path) image_output.open(path, specification) image_output.write_image(image) image_output.close() return True