Skip to content

Commit

Permalink
Fixed #11158 - get_image_dimensions very slow/incorrect after 1 call
Browse files Browse the repository at this point in the history
Thanks to kua for the report, and to kua, SmileyChris and SAn for the patch



git-svn-id: http://code.djangoproject.com/svn/django/trunk@13715 bcc190cf-cafb-0310-a4f2-bffc1f526a37
  • Loading branch information
spookylukey committed Sep 10, 2010
1 parent 443cb9b commit 76249c3
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 7 deletions.
19 changes: 12 additions & 7 deletions django/core/files/images.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,23 +23,26 @@ def _get_image_dimensions(self):
if not hasattr(self, '_dimensions_cache'):
close = self.closed
self.open()
self._dimensions_cache = get_image_dimensions(self)
if close:
self.close()
self._dimensions_cache = get_image_dimensions(self, close=close)
return self._dimensions_cache

def get_image_dimensions(file_or_path):
"""Returns the (width, height) of an image, given an open file or a path."""
def get_image_dimensions(file_or_path, close=False):
"""
Returns the (width, height) of an image, given an open file or a path. Set
'close' to True to close the file at the end if it is initially in an open
state.
"""
# Try to import PIL in either of the two ways it can end up installed.
try:
from PIL import ImageFile as PILImageFile
except ImportError:
import ImageFile as PILImageFile

p = PILImageFile.Parser()
close = False
if hasattr(file_or_path, 'read'):
file = file_or_path
file_pos = file.tell()
file.seek(0)
else:
file = open(file_or_path, 'rb')
close = True
Expand All @@ -55,3 +58,5 @@ def get_image_dimensions(file_or_path):
finally:
if close:
file.close()
else:
file.seek(file_pos)
16 changes: 16 additions & 0 deletions tests/regressiontests/file_storage/tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -230,3 +230,19 @@ def catching_open(*args):
finally:
del images.open
self.assert_(FileWrapper._closed)

class InconsistentGetImageDimensionsBug(TestCase):
"""
Test that get_image_dimensions() works properly after various calls using a file handler (#11158)
"""
def test_multiple_calls(self):
"""
Multiple calls of get_image_dimensions() should return the same size.
"""
from django.core.files.images import ImageFile
img_path = os.path.join(os.path.dirname(__file__), "test.png")
image = ImageFile(open(img_path))
image_pil = Image.open(img_path)
size_1, size_2 = get_image_dimensions(image), get_image_dimensions(image)
self.assertEqual(image_pil.size, size_1)
self.assertEqual(size_1, size_2)

0 comments on commit 76249c3

Please sign in to comment.