diff --git a/skimage/io/_io.py b/skimage/io/_io.py index 8dbc3600..614b0e23 100644 --- a/skimage/io/_io.py +++ b/skimage/io/_io.py @@ -26,7 +26,10 @@ def imread(fname, as_grey=False, plugin=None, flatten=None, If True, convert color images to grey-scale (32-bit floats). Images that are already in grey-scale format are not converted. plugin : str - Name of plugin to use (Python Imaging Library by default). + Name of plugin to use. By default, the different plugins are + tried (starting with the Python Imaging Library) until a suitable + candidate is found. If not given and fname is a tiff file, the + tifffile plugin will be used. Other Parameters ---------------- @@ -50,6 +53,10 @@ def imread(fname, as_grey=False, plugin=None, flatten=None, if flatten is not None: as_grey = flatten + if plugin is None and hasattr(fname, 'lower'): + if fname.lower().endswith(('.tiff', '.tif')): + plugin = 'tifffile' + with file_or_url_context(fname) as fname: img = call_plugin('imread', fname, plugin=plugin, **plugin_args) @@ -109,7 +116,8 @@ def imsave(fname, arr, plugin=None, **plugin_args): plugin : str Name of plugin to use. By default, the different plugins are tried (starting with the Python Imaging Library) until a suitable - candidate is found. + candidate is found. If not given and fname is a tiff file, the + tifffile plugin will be used. Other parameters ---------------- @@ -117,6 +125,9 @@ def imsave(fname, arr, plugin=None, **plugin_args): Passed to the given plugin. """ + if plugin is None and hasattr(fname, 'lower'): + if fname.lower().endswith(('.tiff', '.tif')): + plugin = 'tifffile' if is_low_contrast(arr): warnings.warn('%s is a low contrast image' % fname) return call_plugin('imsave', fname, arr, plugin=plugin, **plugin_args) diff --git a/skimage/io/_plugins/pil_plugin.py b/skimage/io/_plugins/pil_plugin.py index 4028f3e1..7cb8e5c1 100644 --- a/skimage/io/_plugins/pil_plugin.py +++ b/skimage/io/_plugins/pil_plugin.py @@ -5,7 +5,6 @@ from six import string_types from PIL import Image from ...util import img_as_ubyte, img_as_uint -from .tifffile_plugin import imread as tif_imread, imsave as tif_imsave def imread(fname, dtype=None, img_num=None, **kwargs): @@ -21,28 +20,17 @@ def imread(fname, dtype=None, img_num=None, **kwargs): Specifies which image to read in a file with multiple images (zero-indexed). kwargs : keyword pairs, optional - Addition keyword arguments to pass through (only applicable to Tiff - files for now, see `tifffile`'s `imread` function). + Addition keyword arguments to pass through. Notes ----- - Tiff files are handled by Christophe Golhke's tifffile.py [1]_, and support - many advanced image types including multi-page and floating point. - - All other files are read using the Python Imaging Libary. - See PIL docs [2]_ for a list of supported formats. + Files are read using the Python Imaging Libary. + See PIL docs [1]_ for a list of supported formats. References ---------- - .. [1] http://www.lfd.uci.edu/~gohlke/code/tifffile.py.html - .. [2] http://pillow.readthedocs.org/en/latest/handbook/image-file-formats.html - + .. [1] http://pillow.readthedocs.org/en/latest/handbook/image-file-formats.html """ - if hasattr(fname, 'lower') and dtype is None: - kwargs.setdefault('key', img_num) - if fname.lower().endswith(('.tiff', '.tif')): - return tif_imread(fname, **kwargs) - if isinstance(fname, string_types): with open(fname, 'rb') as f: im = Image.open(f) @@ -234,12 +222,8 @@ def imsave(fname, arr, format_str=None, **kwargs): Notes ----- - Tiff files are handled by Christophe Golhke's tifffile.py [1]_, - and support many advanced image types including multi-page and - floating point. - - All other image formats use the Python Imaging Libary. - See PIL docs [2]_ for a list of other supported formats. + Use the Python Imaging Libary. + See PIL docs [1]_ for a list of other supported formats. All images besides single channel PNGs are converted using `img_as_uint8`. Single Channel PNGs have the following behavior: - Integer values in [0, 255] and Boolean types -> img_as_uint8 @@ -247,8 +231,7 @@ def imsave(fname, arr, format_str=None, **kwargs): References ---------- - .. [1] http://www.lfd.uci.edu/~gohlke/code/tifffile.py.html - .. [2] http://pillow.readthedocs.org/en/latest/handbook/image-file-formats.html + .. [1] http://pillow.readthedocs.org/en/latest/handbook/image-file-formats.html """ # default to PNG if file-like object if not isinstance(fname, string_types) and format_str is None: @@ -263,18 +246,6 @@ def imsave(fname, arr, format_str=None, **kwargs): if arr.dtype.kind == 'b': arr = arr.astype(np.uint8) - use_tif = False - if hasattr(fname, 'lower'): - if fname.lower().endswith(('.tiff', '.tif')): - use_tif = True - if format_str is not None: - if format_str.lower() in ['tiff', 'tif']: - use_tif = True - - if use_tif: - tif_imsave(fname, arr, **kwargs) - return - if arr.ndim not in (2, 3): raise ValueError("Invalid shape for image array: %s" % arr.shape) diff --git a/skimage/io/_plugins/tifffile_plugin.py b/skimage/io/_plugins/tifffile_plugin.py index 817776c2..cf1b7279 100644 --- a/skimage/io/_plugins/tifffile_plugin.py +++ b/skimage/io/_plugins/tifffile_plugin.py @@ -24,6 +24,8 @@ def imread(fname, dtype=None, **kwargs): .. [1] http://www.lfd.uci.edu/~gohlke/code/tifffile.py """ + if 'img_num' in kwargs: + kwargs['key'] = kwargs.pop('img_num') with open(fname, 'rb') as f: tif = TiffFile(f) return tif.asarray(**kwargs) diff --git a/skimage/io/tests/test_pil.py b/skimage/io/tests/test_pil.py index 3a53d340..ad3870a6 100644 --- a/skimage/io/tests/test_pil.py +++ b/skimage/io/tests/test_pil.py @@ -196,7 +196,6 @@ def test_all_color(): def test_all_mono(): mono_check('pil') - mono_check('pil', 'tiff') def test_multi_page_gif(): @@ -234,35 +233,5 @@ def test_cmyk(): sim = ssim(refi, newi, dynamic_range=refi.max() - refi.min()) assert sim > 0.99 - -class TestSaveTIF: - def roundtrip(self, dtype, x, compress): - with temporary_file(suffix='.tif') as fname: - if dtype == np.bool: - expected = ['low contrast'] - else: - expected = ['\A\Z'] - with expected_warnings(expected): - if compress > 0: - imsave(fname, x, compress=compress) - else: - imsave(fname, x) - y = imread(fname) - assert_array_equal(x, y) - - def test_imsave_roundtrip(self): - for shape in [(10, 10), (10, 10, 3), (10, 10, 4)]: - for dtype in (np.uint8, np.uint16, np.int16, np.float32, - np.float64, np.bool): - for compress in [0, 2]: - x = np.random.rand(*shape) - - if not np.issubdtype(dtype, float) and \ - not dtype == np.bool: - x = (x * np.iinfo(dtype).max).astype(dtype) - else: - x = x.astype(dtype) - yield self.roundtrip, dtype, x, compress - if __name__ == "__main__": run_module_suite()