diff --git a/CHANGES b/CHANGES index c6f345323..8e7cbf680 100644 --- a/CHANGES +++ b/CHANGES @@ -53,6 +53,7 @@ Features added * #1779: Add EPUB 3 builder * #1751: Add :confval:`todo_link_only` to avoid file path and line indication on :rst:dir:`todolist`. Thanks to Francesco Montesano. +* #2199: Use ``imagesize`` package to obtain size of images Bugs fixed ---------- diff --git a/setup.py b/setup.py index 6d1ae2de4..da85e66a7 100644 --- a/setup.py +++ b/setup.py @@ -53,6 +53,7 @@ requires = [ 'snowballstemmer>=1.1', 'babel>=1.3,!=2.0', 'alabaster>=0.7,<0.8', + 'imagesize', ] extras_require = { # Environment Marker works for wheel 0.24 or later diff --git a/sphinx/util/images.py b/sphinx/util/images.py new file mode 100644 index 000000000..d130ade32 --- /dev/null +++ b/sphinx/util/images.py @@ -0,0 +1,39 @@ +# -*- coding: utf-8 -*- +""" + sphinx.util.images + ~~~~~~~~~~~ + + Image utility functions for Sphinx. + + :copyright: Copyright 2007-2016 by the Sphinx team, see AUTHORS. + :license: BSD, see LICENSE for details. +""" + +import imagesize + +try: + from PIL import Image # check for the Python Imaging Library +except ImportError: + try: + import Image + except ImportError: + Image = None + + +def get_image_size(filename): + try: + size = imagesize.get(filename) + if size[0] == -1: + size = None + + if Image: # fallback to PIL + im = Image.open(filename) + size = im.size + try: + im.fp.close() + except Exception: + pass + + return size + except: + return None diff --git a/sphinx/writers/html.py b/sphinx/writers/html.py index bd65fc52e..2f4a770ad 100644 --- a/sphinx/writers/html.py +++ b/sphinx/writers/html.py @@ -20,16 +20,9 @@ from docutils.writers.html4css1 import Writer, HTMLTranslator as BaseTranslator from sphinx import addnodes from sphinx.locale import admonitionlabels, _ +from sphinx.util.images import get_image_size from sphinx.util.smartypants import sphinx_smarty_pants -try: - from PIL import Image # check for the Python Imaging Library -except ImportError: - try: - import Image - except ImportError: - Image = None - # A good overview of the purpose behind these classes can be found here: # http://www.arnebrodowski.de/blog/write-your-own-restructuredtext-writer.html @@ -481,21 +474,16 @@ class HTMLTranslator(BaseTranslator): # Try to figure out image height and width. Docutils does that too, # but it tries the final file name, which does not necessarily exist # yet at the time the HTML file is written. - if Image and not ('width' in node and 'height' in node): - try: - im = Image.open(os.path.join(self.builder.srcdir, olduri)) - except (IOError, # Source image can't be found or opened - UnicodeError): # PIL doesn't like Unicode paths. - pass + if not ('width' in node and 'height' in node): + size = get_image_size(os.path.join(self.builder.srcdir, olduri)) + if size is None: + self.builder.env.warn_node('Could not obtain image size. ' + ':scale: option is ignored.', node) else: if 'width' not in node: - node['width'] = str(im.size[0]) + node['width'] = str(size[0]) if 'height' not in node: - node['height'] = str(im.size[1]) - try: - im.fp.close() - except Exception: - pass + node['height'] = str(size[1]) BaseTranslator.visit_image(self, node) def visit_toctree(self, node): diff --git a/test-reqs.txt b/test-reqs.txt index 6ab42c342..0edb725dc 100644 --- a/test-reqs.txt +++ b/test-reqs.txt @@ -11,3 +11,4 @@ sqlalchemy>=0.9 whoosh>=2.0 alabaster sphinx_rtd_theme +imagesize