def czi2tif(czifile, tiffile=None, squeeze=True, verbose=True, **kwargs): """Convert CZI file to memory-mappable TIFF file. To read the image data from the created TIFF file: Read the 'StripOffsets' and 'ImageDescription' tags from the first TIFF page. Get the 'dtype' and 'shape' attributes from the ImageDescription string using a JSON decoder. Memory-map 'product(shape) * sizeof(dtype)' bytes in the file starting at StripOffsets[0]. Cast the mapped bytes to an array of 'dtype' and 'shape'. """ verbose = print_ if verbose else lambda *a, **b: None if tiffile is None: tiffile = czifile + '.tif' elif tiffile.lower() == 'none': tiffile = None verbose("\nOpening CZI file... ", end='', flush=True) start_time = time.time() with CziFile(czifile) as czi: if squeeze: shape, axes = squeeze_axes(czi.shape, czi.axes, '') else: shape = czi.shape axes = czi.axes dtype = str(czi.dtype) size = product(shape) * czi.dtype.itemsize verbose("%.3f s" % (time.time() - start_time)) verbose("Image\n axes: %s\n shape: %s\n dtype: %s\n size: %s" % (axes, shape, dtype, format_size(size)), flush=True) if not tiffile: verbose("Copying image from CZI file to RAM... ", end='', flush=True) start_time = time.time() czi.asarray(order=0) else: verbose("Creating empty TIF file... ", end='', flush=True) start_time = time.time() if 'software' not in kwargs: kwargs['software'] = 'czi2tif' metadata = kwargs.pop('metadata', {}) metadata.update(axes=axes, dtype=dtype) data = memmap(tiffile, shape=shape, dtype=dtype, metadata=metadata, **kwargs) data = data.reshape(czi.shape) verbose("%.3f s" % (time.time() - start_time)) verbose("Copying image from CZI to TIF file... ", end='', flush=True) start_time = time.time() czi.asarray(order=0, out=data) verbose("%.3f s" % (time.time() - start_time), flush=True)