##// END OF EJS Templates
ENH: add webp support to IPython.display.Image and complete identification of JPEG,PNG,GIF,WEBP image types by initial bytes
Wes Turner -
Show More
@@ -22,7 +22,8 from . import display_functions
22 22
23 23
24 24 __all__ = ['display_pretty', 'display_html', 'display_markdown',
25 'display_svg', 'display_png', 'display_jpeg', 'display_latex', 'display_json',
25 'display_svg', 'display_png', 'display_jpeg', 'display_webp',
26 'display_latex', 'display_json',
26 27 'display_javascript', 'display_pdf', 'DisplayObject', 'TextDisplayObject',
27 28 'Pretty', 'HTML', 'Markdown', 'Math', 'Latex', 'SVG', 'ProgressBar', 'JSON',
28 29 'GeoJSON', 'Javascript', 'Image', 'set_matplotlib_formats',
@@ -200,6 +201,23 def display_jpeg(*objs, **kwargs):
200 201 _display_mimetype('image/jpeg', objs, **kwargs)
201 202
202 203
204 def display_webp(*objs, **kwargs):
205 """Display the WEBP representation of an object.
206
207 Parameters
208 ----------
209 *objs : object
210 The Python objects to display, or if raw=True raw JPEG data to
211 display.
212 raw : bool
213 Are the data objects raw data or Python objects that need to be
214 formatted before display? [default: False]
215 metadata : dict (optional)
216 Metadata to be associated with the specific mimetype output.
217 """
218 _display_mimetype('image/webp', objs, **kwargs)
219
220
203 221 def display_latex(*objs, **kwargs):
204 222 """Display the LaTeX representation of an object.
205 223
@@ -776,9 +794,12 class Javascript(TextDisplayObject):
776 794 r += _lib_t2*len(self.lib)
777 795 return r
778 796
779 # constants for identifying png/jpeg data
797 # constants for identifying png/jpeg/gif/webp data
780 798 _PNG = b'\x89PNG\r\n\x1a\n'
781 799 _JPEG = b'\xff\xd8'
800 _GIF1 = b"GIF87a"
801 _GIF2 = b"GIF89a"
802 _WEBP = b'WEBP'
782 803
783 804 def _pngxy(data):
784 805 """read the (width, height) from a PNG header"""
@@ -809,6 +830,23 def _gifxy(data):
809 830 """read the (width, height) from a GIF header"""
810 831 return struct.unpack('<HH', data[6:10])
811 832
833 def _webpxy(data):
834 """read the (width, height) from a WEBP header"""
835 if data[12:16] == b"VP8 ":
836 width, height = struct.unpack('<HH', data[24:30])
837 width = (width & 0x3fff)
838 height = (height & 0x3fff)
839 return (width, height)
840 elif data[12:16] == b"VP8L":
841 size_info = struct.unpack('<I', data[21:25])[0]
842 width = 1 + ((size_info & 0x3F) << 8) | (size_info >> 24)
843 height = 1 + ((((size_info >> 8) & 0xF) << 10) |
844 (((size_info >> 14) & 0x3FC) << 2) |
845 ((size_info >> 22) & 0x3))
846 return (width, height)
847 else:
848 raise ValueError("Not a valid WEBP header")
849
812 850
813 851 class Image(DisplayObject):
814 852
@@ -816,11 +854,13 class Image(DisplayObject):
816 854 _FMT_JPEG = u'jpeg'
817 855 _FMT_PNG = u'png'
818 856 _FMT_GIF = u'gif'
819 _ACCEPTABLE_EMBEDDINGS = [_FMT_JPEG, _FMT_PNG, _FMT_GIF]
857 _FMT_WEBP = u'webp'
858 _ACCEPTABLE_EMBEDDINGS = [_FMT_JPEG, _FMT_PNG, _FMT_GIF, _FMT_WEBP]
820 859 _MIMETYPES = {
821 860 _FMT_PNG: 'image/png',
822 861 _FMT_JPEG: 'image/jpeg',
823 862 _FMT_GIF: 'image/gif',
863 _FMT_WEBP: 'image/webp',
824 864 }
825 865
826 866 def __init__(
@@ -858,7 +898,7 class Image(DisplayObject):
858 898 Images from a file are always embedded.
859 899
860 900 format : unicode
861 The format of the image data (png/jpeg/jpg/gif). If a filename or URL is given
901 The format of the image data (png/jpeg/jpg/gif/webp). If a filename or URL is given
862 902 for format will be inferred from the filename extension.
863 903
864 904 embed : bool
@@ -942,6 +982,8 class Image(DisplayObject):
942 982 format = self._FMT_PNG
943 983 elif ext == u'gif':
944 984 format = self._FMT_GIF
985 elif ext == u'webp':
986 format = self._FMT_WEBP
945 987 else:
946 988 format = ext.lower()
947 989 elif isinstance(data, bytes):
@@ -949,6 +991,12 class Image(DisplayObject):
949 991 # only if format has not been specified.
950 992 if data[:2] == _JPEG:
951 993 format = self._FMT_JPEG
994 elif data[:8] == _PNG:
995 format = self._FMT_PNG
996 elif data[8:12] == _WEBP:
997 format = self._FMT_WEBP
998 elif data[:6] == self._GIF1 or data[:6] == self._GIF2:
999 format = self._FMT_GIF
952 1000
953 1001 # failed to detect format, default png
954 1002 if format is None:
General Comments 0
You need to be logged in to leave comments. Login now