def test_tags_rbg_tiled(tmpdir_factory): testfile = "test_data/tiled_rgb_sample.tif" basename = os.path.basename(testfile) with Tiff(testfile) as handle: tags = handle.read_tags() with tifffile.TiffFile(testfile) as handle: page1 = handle.pages[0] tifffile_tags = {} for tag in page1.tags.values(): name, value = tag.name, tag.value tifffile_tags[name] = value image = page1.asarray() compare_tags(tags, tifffile_tags) filename = str(tmpdir_factory.mktemp("write_tags").join(basename)) with Tiff(filename, "w") as handle: handle.set_tags(tags) handle.write(image, method="tile", tile_length=tags[pytiff.tags.tile_length], tile_width=tags[pytiff.tags.tile_width]) with Tiff(filename) as handle: written_tags = handle.read_tags() written_image = handle[:] assert np.all(written_image == image) check_written_tags(written_tags, tags)
def test_cpickle(): t = Tiff(TILED_GREY) data = t[:] t.close() saved = cPickle.dumps(t) loaded = cPickle.loads(saved) loaded_data = loaded[:] loaded.close() np.testing.assert_array_equal(data, loaded_data)
def test_cpickle_multipage(): t = Tiff(MULTI_PAGE) t.set_page(2) data = t[:] t.close() saved = cPickle.dumps(t) loaded = cPickle.loads(saved) loaded_data = loaded[:] loaded.close() np.testing.assert_array_equal(data, loaded_data)
def _load_tif( self, item=None, filename=None, keep=None, explore=False, fractal=False ): """ Notes: PyTiff is not thread safe! Args: item: filename: keep: explore: fractal: Returns: """ # TODO: PyTiff does not properly handle exceeding bounds! Users might expect behaviour similar to numpy. PyTiff may show integer overflow and raise MemoryError as a consequence. # TODO: Fix this either in PyTiff or check for bounds here. filename = self.filename if filename is None else filename keep = self._keep if keep is None else keep fh_key = filename + f'::{str(self._page)}' res = None if keep: try: t = self.file_handles[fh_key] except KeyError: self.file_handles[fh_key] = t = Tiff(filename) t.set_page(self._page) if explore: self._update_meta(t) else: res = t[:] if item is None else t[item] else: with Tiff(filename) as t: t.set_page(self._page) if explore: self._update_meta(t) else: res = t[:] if item is None else t[item] if not fractal and not explore: res = self._apply_callbacks(res) if self._all_item(item): self._set_data(res) return res
def to_tiff(filename, image, mode='w', method='tile', bigtiff=True): """To tiff file. Write ``image`` to tiff file using ``pytiff``. By default, the tiff is tiled, s.t. crops can be read from disk without loading the entire image into memory first. Notes: - ``pytiff`` must be installed to use this function. References: https://pytiff.readthedocs.io/en/master/quickstart.html Args: filename: File name. image: Image. mode: Mode. method: Method. Either ``'tile'`` or ``'scanline'``. bigtiff: Whether to use bigtiff format. """ try: from pytiff import Tiff except ModuleNotFoundError: raise ModuleNotFoundError( 'To use the to_tiff function pytiff must be installed.\n' 'See: https://pytiff.readthedocs.io/en/master/quickstart.html') with Tiff(filename, mode, bigtiff=bigtiff) as handle: handle.write(image, method=method)
def load_image(name, method='imageio') -> np.ndarray: """Load image. Load image from URL or from filename via ``imageio`` or ``pytiff``. Args: name: URL (must start with ``http``) or filename. method: Method to use for filenames. Returns: Image. """ if name.startswith('http'): img = fetch_image(name) elif method == 'imageio': from imageio import imread img = imread(name) elif method == 'pytiff': from pytiff import Tiff with Tiff(name, 'r') as t: img = t[:] else: raise ValueError( f'Could not load {name} with method {method}. Also note that URLs should start with "http".' ) return img
def to_tifs( self, filename: str, method='tile', tile_height: int = 240, tile_width: int = None, min_is_black: bool = True, compression: int = 1, planar_config: int = 1 ): if filename.endswith('.tif'): stub = filename[:-len('.tif')] ending = '.tif' elif filename.endswith('.tiff'): stub = filename[:-len('.tiff')] ending = '.tiff' else: stub = filename ending = '.tif' if tile_width is None: tile_width = tile_height dims = self.guess_spatial_dimensions() rs = self.shape[2:dims] nums = [min(2, int(np.ceil(np.log10(i)))) for i in rs] for i in range(int(np.prod(rs))): indices = np.unravel_index(i, rs) sel = (slice(None), slice(None)) + tuple(indices) suffix = '_'.join([f'%0{n}d' % index for n, index in zip(nums, indices)]) with Tiff(stub + '_Slice' + suffix + ending, 'w') as handle: handle.write(self.lazy_load(sel), method=method, tile_width=tile_width, tile_length=tile_height, photometric=int(min_is_black), compression=compression, planar_config=planar_config)
def to_tif( self, filename: str, method='tile', tile_height: int = 240, tile_width: int = None, min_is_black: bool = True, compression: int = 1, planar_config: int = 1 ): """Write data to tif file. Args: filename: Name of tif file. method: One of ('tile', 'scanline'). Determines which method is used for writing. 'scanline' is recommended for compatibility with common image viewers, 'tile' is recommended for large images. tile_height: Tile length. Only relevant for tile method. tile_width: Tile width. Only relevant for tile method. min_is_black: Whether minimum value represents black color. If False minimum values represent white color. compression: Compression level. Value 1 for no compression. planar_config: Defaults to 1, component values for each pixel are stored contiguously. 2 says components are stored in component planes. Irrelevant for greyscale images. """ if tile_width is None: tile_width = tile_height with Tiff(filename, 'w') as handle: handle.write(self[:], method=method, tile_width=tile_width, tile_length=tile_height, photometric=int(min_is_black), compression=compression, planar_config=planar_config)
def to_pyr_tif( self, filename, method='tile', tile_height=256, tile_width=None, min_is_black: bool = True, compression: int = 1, planar_config: int = 1, max_pages=9, min_size: int = 42, dtype=np.uint8 ): """Write data to pyramid tif. Writes paged tif file. Page 0 is largest, each page reduces image size by half. This can be viewed as the reversed DZI standard. References: http://schemas.microsoft.com/deepzoom/2008 Args: filename: Name of tif file. method: One of ('tile', 'scanline'). Determines which method is used for writing. 'scanline' is recommended for compatibility with common image viewers, 'tile' is recommended for large images. tile_height: Tile length. Only relevant for tile method. tile_width: Tile width. Only relevant for tile method. min_is_black: Whether minimum value represents black color. If False minimum values represent white color. compression: Compression level. Value 1 for no compression. planar_config: Defaults to 1, component values for each pixel are stored contiguously. 2 says components are stored in component planes. Irrelevant for greyscale images. max_pages: Maximum number of pages. If image size is less than `min_size` at any dimension no further pages are generated. min_size: Minimal allowed spatial image dimension size. dtype: Data type Returns: None """ from cv2 import pyrDown if tile_width is None: tile_width = tile_height inputs = self[:] with Tiff(filename, 'w', bigtiff=True) as o: for page in range(max_pages): if inputs.dtype != dtype: inputs = inputs.astype(dtype) gc.collect() o.write(inputs, method=method, tile_width=tile_width, tile_length=tile_height, photometric=int(min_is_black), compression=compression, planar_config=planar_config) if np.any((np.array(inputs.shape[:2]) * .5) < min_size): break if page + 1 >= max_pages: inputs = None else: inputs = pyrDown(inputs) gc.collect()
def test_tags_rbg(): testfile = "test_data/rgb_sample.tif" basename = os.path.basename(testfile) with Tiff(testfile) as handle: tags = handle.read_tags() with tifffile.TiffFile(testfile) as handle: page1 = handle.pages[0] tifffile_tags = {} for tag in page1.tags.values(): name, value = tag.name, tag.value tifffile_tags[name] = value image = page1.asarray() compare_tags(tags, tifffile_tags)
def test_tags_unicode(tmpdir_factory): testfile = "test_data/unicode_imagedescription.tif" basename = os.path.basename(testfile) # Read a UTF-8 tag as bytes. with Tiff(testfile) as handle: tags = handle.read_tags() with tifffile.TiffFile(testfile) as handle: page1 = handle.pages[0] tifffile_tags = {} for tag in page1.tags.values(): name, value = tag.name, tag.value tifffile_tags[name] = value image = page1.asarray() compare_tags(tags, tifffile_tags) # Decode UTF-8 in a tag. with Tiff(testfile, encoding='utf-8') as handle: tags_unicode = handle.read_tags() compare_tags(tags_unicode, tifffile_tags, encoding='utf-8') # Decoding UTF-8 as ascii should error. with pytest.raises(UnicodeDecodeError): _ = Tiff(testfile, encoding='ascii') # Write a pre-encoded UTF-8 tag (bytes). filename = str(tmpdir_factory.mktemp("write_tags").join(basename)) with Tiff(filename, "w") as handle: handle.set_tags(tags) handle.write(image, method="tile", tile_length=tags[pytiff.tags.tile_length], tile_width=tags[pytiff.tags.tile_width]) with Tiff(filename) as handle: written_tags = handle.read_tags() written_image = handle[:] assert np.all(written_image == image) check_written_tags(written_tags, tags) # Encode a unicode tag as UTF-8. filename = str(tmpdir_factory.mktemp("write_tags").join(basename)) with Tiff(filename, "w", encoding='utf-8') as handle: handle.set_tags(tags_unicode) handle.write(image, method="tile", tile_length=tags_unicode[pytiff.tags.tile_length], tile_width=tags_unicode[pytiff.tags.tile_width]) with Tiff(filename, encoding='utf-8') as handle: written_tags = handle.read_tags() written_image = handle[:] assert np.all(written_image == image) check_written_tags(written_tags, tags_unicode) # Write a unicode tag containing only ascii, without explicit encoding. filename = str(tmpdir_factory.mktemp("write_tags").join(basename)) tags_unicode2 = tags.copy() tags_unicode2[pytiff.tags.image_description] = u'pytiff' with Tiff(filename, "w") as handle: handle.set_tags(tags_unicode2) handle.write(image, method="tile", tile_length=tags_unicode2[pytiff.tags.tile_length], tile_width=tags_unicode2[pytiff.tags.tile_width]) with Tiff(filename, encoding='ascii') as handle: written_tags = handle.read_tags() written_image = handle[:] assert np.all(written_image == image) check_written_tags(written_tags, tags_unicode2) # Implicitly encode a unicode tag, but only under Python 3 (for backwards # compatibility with old API). if sys.version_info[0] == 3: filename = str(tmpdir_factory.mktemp("write_tags").join(basename)) with Tiff(filename, "w") as handle: handle.set_tags(tags_unicode) handle.write(image, method="tile", tile_length=tags_unicode[pytiff.tags.tile_length], tile_width=tags_unicode[pytiff.tags.tile_width]) with Tiff(filename, encoding='utf-8') as handle: written_tags = handle.read_tags() written_image = handle[:] assert np.all(written_image == image) check_written_tags(written_tags, tags_unicode)