Allow keyword arguments to imsave for PIL plugin

Certain formats allow additional arguments, such as `compress=` for
TIFF or `quality=` for JPEG. Without this patch, the plugin simply
does not allow these arguments to be passed.
This commit is contained in:
Juan Nunez-Iglesias
2015-03-31 00:24:23 +11:00
parent 3e9506c6b3
commit b6f2125e71
2 changed files with 38 additions and 11 deletions
+9 -3
View File
@@ -196,7 +196,7 @@ def ndarray_to_pil(arr, format_str=None):
return im
def imsave(fname, arr, format_str=None):
def imsave(fname, arr, format_str=None, **kwargs):
"""Save an image to disk.
Parameters
@@ -210,6 +210,12 @@ def imsave(fname, arr, format_str=None):
format_str: str
Format to save as, this is defaulted to PNG if using a file-like
object; this will be derived from the extension if fname is a string
kwargs: dict
Keyword arguments to the Pillow save function (or tifffile save
function, for Tiff files). These are format dependent. For example,
Pillow's JPEG save function supports an integer ``quality`` argument
with values in [1, 95], while TIFFFile supports a ``compress``
integer argument with values in [0, 9].
Notes
-----
@@ -251,7 +257,7 @@ def imsave(fname, arr, format_str=None):
use_tif = True
if use_tif:
tif_imsave(fname, arr)
tif_imsave(fname, arr, **kwargs)
return
if arr.ndim not in (2, 3):
@@ -262,4 +268,4 @@ def imsave(fname, arr, format_str=None):
raise ValueError("Invalid number of channels in image array.")
img = ndarray_to_pil(arr, format_str=format_str)
img.save(fname, format=format_str)
img.save(fname, format=format_str, **kwargs)
+29 -8
View File
@@ -97,6 +97,17 @@ def test_imread_truncated_jpg():
os.path.join(data_dir, 'truncated.jpg'))
def test_jpg_quality_arg():
chessboard = np.load(os.path.join(data_dir, 'chessboard_GRAY_U8.npy'))
with NamedTemporaryFile(suffix='.jpg') as jpg:
fname = jpg.name
imsave(fname, chessboard, quality=95)
im = imread(fname)
sim = ssim(chessboard, im,
dynamic_range=chessboard.max() - chessboard.min())
assert sim > 0.99
def test_imread_uint16_big_endian():
expected = np.load(os.path.join(data_dir, 'chessboard_GRAY_U8.npy'))
img = imread(os.path.join(data_dir, 'chessboard_GRAY_U16B.tif'))
@@ -214,11 +225,19 @@ def test_cmyk():
class TestSaveTIF:
def roundtrip(self, dtype, x):
def roundtrip(self, dtype, x, compress):
f = NamedTemporaryFile(suffix='.tif')
fname = f.name
f.close()
imsave(fname, x)
if dtype == np.bool:
expected = ['low contrast']
else:
expected = []
with expected_warnings(expected):
if compress > 0:
imsave(fname, x, compress=compress)
else:
imsave(fname, x)
y = imread(fname)
assert_array_equal(x, y)
@@ -226,13 +245,15 @@ class TestSaveTIF:
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):
x = np.random.rand(*shape)
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
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()