Merge pull request #1604 from blink1073/pil-close

FIX: Do not let PIL manage the file handle.
This commit is contained in:
Josh Warner
2015-07-14 21:47:32 -05:00
5 changed files with 60 additions and 27 deletions
+7 -7
View File
@@ -93,8 +93,8 @@ def roundtrip(img, plugin, suffix):
if not '.' in suffix:
suffix = '.' + suffix
temp_file = NamedTemporaryFile(suffix=suffix, delete=False)
temp_file.close()
fname = temp_file.name
temp_file.close()
io.imsave(fname, img, plugin=plugin)
new = io.imread(fname, plugin=plugin)
try:
@@ -119,7 +119,7 @@ def color_check(plugin, fmt='png'):
testing.assert_allclose(img2.astype(np.uint8), r2)
img3 = img_as_float(img)
with expected_warnings(['precision loss|unclosed file']):
with expected_warnings(['precision loss']):
r3 = roundtrip(img3, plugin, fmt)
testing.assert_allclose(r3, img)
@@ -131,12 +131,12 @@ def color_check(plugin, fmt='png'):
r4 = roundtrip(img4, plugin, fmt)
testing.assert_allclose(r4, img4)
else:
with expected_warnings(['sign loss|precision loss|unclosed file']):
with expected_warnings(['sign loss|precision loss']):
r4 = roundtrip(img4, plugin, fmt)
testing.assert_allclose(r4, img_as_ubyte(img4))
img5 = img_as_uint(img)
with expected_warnings(['precision loss|unclosed file']):
with expected_warnings(['precision loss']):
r5 = roundtrip(img5, plugin, fmt)
testing.assert_allclose(r5, img)
@@ -156,14 +156,14 @@ def mono_check(plugin, fmt='png'):
testing.assert_allclose(img2.astype(np.uint8), r2)
img3 = img_as_float(img)
with expected_warnings(['precision|unclosed file|\A\Z']):
with expected_warnings(['precision|\A\Z']):
r3 = roundtrip(img3, plugin, fmt)
if r3.dtype.kind == 'f':
testing.assert_allclose(img3, r3)
else:
testing.assert_allclose(r3, img_as_uint(img))
with expected_warnings(['precision loss|unclosed file']):
with expected_warnings(['precision loss']):
img4 = img_as_int(img)
if fmt.lower() in (('tif', 'tiff')):
img4 -= 100
@@ -171,7 +171,7 @@ def mono_check(plugin, fmt='png'):
r4 = roundtrip(img4, plugin, fmt)
testing.assert_allclose(r4, img4)
else:
with expected_warnings(['precision loss|sign loss|unclosed file']):
with expected_warnings(['precision loss|sign loss']):
r4 = roundtrip(img4, plugin, fmt)
testing.assert_allclose(r4, img_as_uint(img4))
+19 -14
View File
@@ -5,7 +5,7 @@ from six import string_types
from PIL import Image
from ...util import img_as_ubyte, img_as_uint
from ...external.tifffile import imread as tif_imread, imsave as tif_imsave
from .tifffile_plugin import imread as tif_imread, imsave as tif_imsave
def imread(fname, dtype=None, img_num=None, **kwargs):
@@ -13,8 +13,8 @@ def imread(fname, dtype=None, img_num=None, **kwargs):
Parameters
----------
fname : str
File name.
fname : str or file
File name or file-like-object.
dtype : numpy dtype object or string specifier
Specifies data type of array elements.
img_num : int, optional
@@ -43,18 +43,12 @@ def imread(fname, dtype=None, img_num=None, **kwargs):
if fname.lower().endswith(('.tiff', '.tif')):
return tif_imread(fname, **kwargs)
im = Image.open(fname)
try:
# this will raise an IOError if the file is not readable
im.getdata()[0]
except IOError as e:
site = "http://pillow.readthedocs.org/en/latest/installation.html#external-libraries"
pillow_error_message = str(e)
error_message = ('Could not load "%s" \n'
'Reason: "%s"\n'
'Please see documentation at: %s') % (fname, pillow_error_message, site)
raise ValueError(error_message)
if isinstance(fname, string_types):
with open(fname, 'rb') as f:
im = Image.open(f)
return pil_to_ndarray(im, dtype=dtype, img_num=img_num)
else:
im = Image.open(fname)
return pil_to_ndarray(im, dtype=dtype, img_num=img_num)
@@ -66,6 +60,17 @@ def pil_to_ndarray(im, dtype=None, img_num=None):
Refer to ``imread``.
"""
try:
# this will raise an IOError if the file is not readable
im.getdata()[0]
except IOError as e:
site = "http://pillow.readthedocs.org/en/latest/installation.html#external-libraries"
pillow_error_message = str(e)
error_message = ('Could not load "%s" \n'
'Reason: "%s"\n'
'Please see documentation at: %s'
% (im.filename, pillow_error_message, site))
raise ValueError(error_message)
frames = []
grayscale = None
i = 0
+28 -1
View File
@@ -1 +1,28 @@
from ...external.tifffile import imread, imsave
from ...external.tifffile import TiffFile, imsave
def imread(fname, dtype=None, **kwargs):
"""Load a tiff image from file.
Parameters
----------
fname : str or file
File name or file-like-object.
dtype : numpy dtype object or string specifier
Specifies data type of array elements (Not currently used).
kwargs : keyword pairs, optional
Addition keyword arguments to pass through (see `tifffile`'s `imread` function).
Notes
-----
Provided by Christophe Golhke's tifffile.py [1]_, and supports many
advanced image types including multi-page and floating point.
References
----------
.. [1] http://www.lfd.uci.edu/~gohlke/code/tifffile.py
"""
with open(fname, 'rb') as f:
tif = TiffFile(f)
return tif.asarray(**kwargs)
+3 -2
View File
@@ -199,8 +199,9 @@ class ImageCollection(object):
index = []
for fname in self._files:
if fname.lower().endswith(('.tiff', '.tif')):
img = TiffFile(fname)
index += [(fname, i) for i in range(len(img.pages))]
with open(fname, 'rb') as f:
img = TiffFile(f)
index += [(fname, i) for i in range(len(img.pages))]
else:
try:
im = Image.open(fname)
+3 -3
View File
@@ -160,7 +160,7 @@ def test_imsave_filelike():
s = BytesIO()
# save to file-like object
with expected_warnings(['precision loss|unclosed file',
with expected_warnings(['precision loss',
'is a low contrast image']):
imsave(s, image)
@@ -230,9 +230,9 @@ class TestSaveTIF:
def roundtrip(self, dtype, x, compress):
with temporary_file(suffix='.tif') as fname:
if dtype == np.bool:
expected = ['low contrast|unclosed file']
expected = ['low contrast']
else:
expected = ['unclosed file|\A\Z']
expected = ['\A\Z']
with expected_warnings(expected):
if compress > 0:
imsave(fname, x, compress=compress)