Show More
@@ -21,13 +21,35 b' from IPython.testing.skipdoctest import skip_doctest' | |||||
21 | from . import display_functions |
|
21 | from . import display_functions | |
22 |
|
22 | |||
23 |
|
23 | |||
24 | __all__ = ['display_pretty', 'display_html', 'display_markdown', |
|
24 | __all__ = [ | |
25 | 'display_svg', 'display_png', 'display_jpeg', 'display_latex', 'display_json', |
|
25 | "display_pretty", | |
26 | 'display_javascript', 'display_pdf', 'DisplayObject', 'TextDisplayObject', |
|
26 | "display_html", | |
27 | 'Pretty', 'HTML', 'Markdown', 'Math', 'Latex', 'SVG', 'ProgressBar', 'JSON', |
|
27 | "display_markdown", | |
28 | 'GeoJSON', 'Javascript', 'Image', 'set_matplotlib_formats', |
|
28 | "display_svg", | |
29 | 'set_matplotlib_close', |
|
29 | "display_png", | |
30 | 'Video'] |
|
30 | "display_jpeg", | |
|
31 | "display_webp", | |||
|
32 | "display_latex", | |||
|
33 | "display_json", | |||
|
34 | "display_javascript", | |||
|
35 | "display_pdf", | |||
|
36 | "DisplayObject", | |||
|
37 | "TextDisplayObject", | |||
|
38 | "Pretty", | |||
|
39 | "HTML", | |||
|
40 | "Markdown", | |||
|
41 | "Math", | |||
|
42 | "Latex", | |||
|
43 | "SVG", | |||
|
44 | "ProgressBar", | |||
|
45 | "JSON", | |||
|
46 | "GeoJSON", | |||
|
47 | "Javascript", | |||
|
48 | "Image", | |||
|
49 | "set_matplotlib_formats", | |||
|
50 | "set_matplotlib_close", | |||
|
51 | "Video", | |||
|
52 | ] | |||
31 |
|
53 | |||
32 | _deprecated_names = ["display", "clear_output", "publish_display_data", "update_display", "DisplayHandle"] |
|
54 | _deprecated_names = ["display", "clear_output", "publish_display_data", "update_display", "DisplayHandle"] | |
33 |
|
55 | |||
@@ -200,6 +222,23 b' def display_jpeg(*objs, **kwargs):' | |||||
200 | _display_mimetype('image/jpeg', objs, **kwargs) |
|
222 | _display_mimetype('image/jpeg', objs, **kwargs) | |
201 |
|
223 | |||
202 |
|
224 | |||
|
225 | def display_webp(*objs, **kwargs): | |||
|
226 | """Display the WEBP representation of an object. | |||
|
227 | ||||
|
228 | Parameters | |||
|
229 | ---------- | |||
|
230 | *objs : object | |||
|
231 | The Python objects to display, or if raw=True raw JPEG data to | |||
|
232 | display. | |||
|
233 | raw : bool | |||
|
234 | Are the data objects raw data or Python objects that need to be | |||
|
235 | formatted before display? [default: False] | |||
|
236 | metadata : dict (optional) | |||
|
237 | Metadata to be associated with the specific mimetype output. | |||
|
238 | """ | |||
|
239 | _display_mimetype("image/webp", objs, **kwargs) | |||
|
240 | ||||
|
241 | ||||
203 | def display_latex(*objs, **kwargs): |
|
242 | def display_latex(*objs, **kwargs): | |
204 | """Display the LaTeX representation of an object. |
|
243 | """Display the LaTeX representation of an object. | |
205 |
|
244 | |||
@@ -776,9 +815,14 b' class Javascript(TextDisplayObject):' | |||||
776 | r += _lib_t2*len(self.lib) |
|
815 | r += _lib_t2*len(self.lib) | |
777 | return r |
|
816 | return r | |
778 |
|
817 | |||
779 | # constants for identifying png/jpeg data |
|
818 | ||
780 | _PNG = b'\x89PNG\r\n\x1a\n' |
|
819 | # constants for identifying png/jpeg/gif/webp data | |
781 | _JPEG = b'\xff\xd8' |
|
820 | _PNG = b"\x89PNG\r\n\x1a\n" | |
|
821 | _JPEG = b"\xff\xd8" | |||
|
822 | _GIF1 = b"GIF87a" | |||
|
823 | _GIF2 = b"GIF89a" | |||
|
824 | _WEBP = b"WEBP" | |||
|
825 | ||||
782 |
|
826 | |||
783 | def _pngxy(data): |
|
827 | def _pngxy(data): | |
784 | """read the (width, height) from a PNG header""" |
|
828 | """read the (width, height) from a PNG header""" | |
@@ -786,6 +830,7 b' def _pngxy(data):' | |||||
786 | # next 8 bytes are width/height |
|
830 | # next 8 bytes are width/height | |
787 | return struct.unpack('>ii', data[ihdr+4:ihdr+12]) |
|
831 | return struct.unpack('>ii', data[ihdr+4:ihdr+12]) | |
788 |
|
832 | |||
|
833 | ||||
789 | def _jpegxy(data): |
|
834 | def _jpegxy(data): | |
790 | """read the (width, height) from a JPEG header""" |
|
835 | """read the (width, height) from a JPEG header""" | |
791 | # adapted from http://www.64lines.com/jpeg-width-height |
|
836 | # adapted from http://www.64lines.com/jpeg-width-height | |
@@ -805,22 +850,45 b' def _jpegxy(data):' | |||||
805 | h, w = struct.unpack('>HH', data[iSOF+5:iSOF+9]) |
|
850 | h, w = struct.unpack('>HH', data[iSOF+5:iSOF+9]) | |
806 | return w, h |
|
851 | return w, h | |
807 |
|
852 | |||
|
853 | ||||
808 | def _gifxy(data): |
|
854 | def _gifxy(data): | |
809 | """read the (width, height) from a GIF header""" |
|
855 | """read the (width, height) from a GIF header""" | |
810 | return struct.unpack('<HH', data[6:10]) |
|
856 | return struct.unpack('<HH', data[6:10]) | |
811 |
|
857 | |||
812 |
|
858 | |||
|
859 | def _webpxy(data): | |||
|
860 | """read the (width, height) from a WEBP header""" | |||
|
861 | if data[12:16] == b"VP8 ": | |||
|
862 | width, height = struct.unpack("<HH", data[24:30]) | |||
|
863 | width = width & 0x3FFF | |||
|
864 | height = height & 0x3FFF | |||
|
865 | return (width, height) | |||
|
866 | elif data[12:16] == b"VP8L": | |||
|
867 | size_info = struct.unpack("<I", data[21:25])[0] | |||
|
868 | width = 1 + ((size_info & 0x3F) << 8) | (size_info >> 24) | |||
|
869 | height = 1 + ( | |||
|
870 | (((size_info >> 8) & 0xF) << 10) | |||
|
871 | | (((size_info >> 14) & 0x3FC) << 2) | |||
|
872 | | ((size_info >> 22) & 0x3) | |||
|
873 | ) | |||
|
874 | return (width, height) | |||
|
875 | else: | |||
|
876 | raise ValueError("Not a valid WEBP header") | |||
|
877 | ||||
|
878 | ||||
813 | class Image(DisplayObject): |
|
879 | class Image(DisplayObject): | |
814 |
|
880 | |||
815 |
_read_flags = |
|
881 | _read_flags = "rb" | |
816 |
_FMT_JPEG = |
|
882 | _FMT_JPEG = "jpeg" | |
817 |
_FMT_PNG = |
|
883 | _FMT_PNG = "png" | |
818 |
_FMT_GIF = |
|
884 | _FMT_GIF = "gif" | |
819 | _ACCEPTABLE_EMBEDDINGS = [_FMT_JPEG, _FMT_PNG, _FMT_GIF] |
|
885 | _FMT_WEBP = "webp" | |
|
886 | _ACCEPTABLE_EMBEDDINGS = [_FMT_JPEG, _FMT_PNG, _FMT_GIF, _FMT_WEBP] | |||
820 | _MIMETYPES = { |
|
887 | _MIMETYPES = { | |
821 |
_FMT_PNG: |
|
888 | _FMT_PNG: "image/png", | |
822 |
_FMT_JPEG: |
|
889 | _FMT_JPEG: "image/jpeg", | |
823 |
_FMT_GIF: |
|
890 | _FMT_GIF: "image/gif", | |
|
891 | _FMT_WEBP: "image/webp", | |||
824 | } |
|
892 | } | |
825 |
|
893 | |||
826 | def __init__( |
|
894 | def __init__( | |
@@ -837,7 +905,7 b' class Image(DisplayObject):' | |||||
837 | metadata=None, |
|
905 | metadata=None, | |
838 | alt=None, |
|
906 | alt=None, | |
839 | ): |
|
907 | ): | |
840 | """Create a PNG/JPEG/GIF image object given raw data. |
|
908 | """Create a PNG/JPEG/GIF/WEBP image object given raw data. | |
841 |
|
909 | |||
842 | When this object is returned by an input cell or passed to the |
|
910 | When this object is returned by an input cell or passed to the | |
843 | display function, it will result in the image being displayed |
|
911 | display function, it will result in the image being displayed | |
@@ -858,7 +926,7 b' class Image(DisplayObject):' | |||||
858 | Images from a file are always embedded. |
|
926 | Images from a file are always embedded. | |
859 |
|
927 | |||
860 | format : unicode |
|
928 | format : unicode | |
861 | The format of the image data (png/jpeg/jpg/gif). If a filename or URL is given |
|
929 | The format of the image data (png/jpeg/jpg/gif/webp). If a filename or URL is given | |
862 | for format will be inferred from the filename extension. |
|
930 | for format will be inferred from the filename extension. | |
863 |
|
931 | |||
864 | embed : bool |
|
932 | embed : bool | |
@@ -942,6 +1010,8 b' class Image(DisplayObject):' | |||||
942 | format = self._FMT_PNG |
|
1010 | format = self._FMT_PNG | |
943 | elif ext == u'gif': |
|
1011 | elif ext == u'gif': | |
944 | format = self._FMT_GIF |
|
1012 | format = self._FMT_GIF | |
|
1013 | elif ext == "webp": | |||
|
1014 | format = self._FMT_WEBP | |||
945 | else: |
|
1015 | else: | |
946 | format = ext.lower() |
|
1016 | format = ext.lower() | |
947 | elif isinstance(data, bytes): |
|
1017 | elif isinstance(data, bytes): | |
@@ -949,6 +1019,12 b' class Image(DisplayObject):' | |||||
949 | # only if format has not been specified. |
|
1019 | # only if format has not been specified. | |
950 | if data[:2] == _JPEG: |
|
1020 | if data[:2] == _JPEG: | |
951 | format = self._FMT_JPEG |
|
1021 | format = self._FMT_JPEG | |
|
1022 | elif data[:8] == _PNG: | |||
|
1023 | format = self._FMT_PNG | |||
|
1024 | elif data[8:12] == _WEBP: | |||
|
1025 | format = self._FMT_WEBP | |||
|
1026 | elif data[:6] == _GIF1 or data[:6] == _GIF2: | |||
|
1027 | format = self._FMT_GIF | |||
952 |
|
1028 | |||
953 | # failed to detect format, default png |
|
1029 | # failed to detect format, default png | |
954 | if format is None: |
|
1030 | if format is None: |
@@ -1,6 +1,15 b'' | |||||
1 | ============ |
|
1 | ============ | |
2 | 8.x Series |
|
2 | 8.x Series | |
3 | ============ |
|
3 | ============ | |
|
4 | ||||
|
5 | .. _version 8.29: | |||
|
6 | ||||
|
7 | IPython 8.29 | |||
|
8 | ============ | |||
|
9 | ||||
|
10 | ||||
|
11 | - Add support for WEBP to ``IPython.display.Image``. :ghpull:`14526` | |||
|
12 | ||||
4 | .. _version 8.28: |
|
13 | .. _version 8.28: | |
5 |
|
14 | |||
6 | IPython 8.28 |
|
15 | IPython 8.28 |
General Comments 0
You need to be logged in to leave comments.
Login now