Show More
@@ -23,7 +23,7 b' from IPython.utils.py3compat import cast_unicode' | |||
|
23 | 23 | from IPython.testing.skipdoctest import skip_doctest |
|
24 | 24 | |
|
25 | 25 | __all__ = ['display', 'display_pretty', 'display_html', 'display_markdown', |
|
26 |
'display_svg', 'display_png', 'display_jpeg', ' |
|
|
26 | 'display_svg', 'display_png', 'display_jpeg', 'display_latex', 'display_json', | |
|
27 | 27 | 'display_javascript', 'display_pdf', 'DisplayObject', 'TextDisplayObject', |
|
28 | 28 | 'Pretty', 'HTML', 'Markdown', 'Math', 'Latex', 'SVG', 'JSON', 'GeoJSON', 'Javascript', |
|
29 | 29 | 'Image', 'clear_output', 'set_matplotlib_formats', 'set_matplotlib_close', |
@@ -86,18 +86,7 b' def publish_display_data(data, metadata=None, source=None, *, transient=None, **' | |||
|
86 | 86 | See the ``display_data`` message in the messaging documentation for |
|
87 | 87 | more details about this message type. |
|
88 | 88 | |
|
89 | The following MIME types are currently implemented: | |
|
90 | ||
|
91 | * text/plain | |
|
92 | * text/html | |
|
93 | * text/markdown | |
|
94 | * text/latex | |
|
95 | * application/json | |
|
96 | * application/javascript | |
|
97 | * image/png | |
|
98 | * image/jpeg | |
|
99 | * image/gif | |
|
100 | * image/svg+xml | |
|
89 | Keys of data and metadata can be any mime-type. | |
|
101 | 90 | |
|
102 | 91 | Parameters |
|
103 | 92 | ---------- |
@@ -257,11 +246,11 b' def display(*objs, include=None, exclude=None, metadata=None, transient=None, di' | |||
|
257 | 246 | - `_repr_json_`: return a JSONable dict |
|
258 | 247 | - `_repr_jpeg_`: return raw JPEG data |
|
259 | 248 | - `_repr_png_`: return raw PNG data |
|
260 | - `_repr_gif_`: return raw GIF data | |
|
261 | 249 | - `_repr_svg_`: return raw SVG data as a string |
|
262 | 250 | - `_repr_latex_`: return LaTeX commands in a string surrounded by "$". |
|
263 | 251 | - `_repr_mimebundle_`: return a full mimebundle containing the mapping |
|
264 | from all mimetypes to data | |
|
252 | from all mimetypes to data. | |
|
253 | Use this for any mime-type not listed above. | |
|
265 | 254 | |
|
266 | 255 | When you are directly writing your own classes, you can adapt them for |
|
267 | 256 | display in IPython by following the above approach. But in practice, you |
@@ -496,22 +485,6 b' def display_jpeg(*objs, **kwargs):' | |||
|
496 | 485 | Metadata to be associated with the specific mimetype output. |
|
497 | 486 | """ |
|
498 | 487 | _display_mimetype('image/jpeg', objs, **kwargs) |
|
499 | ||
|
500 | def display_gif(*objs, **kwargs): | |
|
501 | """Display the GIF representation of an object. | |
|
502 | ||
|
503 | Parameters | |
|
504 | ---------- | |
|
505 | objs : tuple of objects | |
|
506 | The Python objects to display, or if raw=True raw gif data to | |
|
507 | display. | |
|
508 | raw : bool | |
|
509 | Are the data objects raw data or Python objects that need to be | |
|
510 | formatted before display? [default: False] | |
|
511 | metadata : dict (optional) | |
|
512 | Metadata to be associated with the specific mimetype output. | |
|
513 | """ | |
|
514 | _display_mimetype('image/gif', objs, **kwargs) | |
|
515 | 488 | |
|
516 | 489 | |
|
517 | 490 | def display_latex(*objs, **kwargs): |
@@ -984,11 +957,12 b' def _jpegxy(data):' | |||
|
984 | 957 | idx += 2 |
|
985 | 958 | |
|
986 | 959 | return struct.unpack('>HH', data[iSOF+5:iSOF+9]) |
|
987 | ||
|
960 | ||
|
988 | 961 | def _gifxy(data): |
|
989 | 962 | """read the (width, height) from a GIF header""" |
|
990 | 963 | return struct.unpack('<HH', data[6:10]) |
|
991 | 964 | |
|
965 | ||
|
992 | 966 | class Image(DisplayObject): |
|
993 | 967 | |
|
994 | 968 | _read_flags = 'rb' |
@@ -996,6 +970,11 b' class Image(DisplayObject):' | |||
|
996 | 970 | _FMT_PNG = u'png' |
|
997 | 971 | _FMT_GIF = u'gif' |
|
998 | 972 | _ACCEPTABLE_EMBEDDINGS = [_FMT_JPEG, _FMT_PNG, _FMT_GIF] |
|
973 | _MIMETYPES = { | |
|
974 | _FMT_PNG: 'image/png', | |
|
975 | _FMT_JPEG: 'image/jpeg', | |
|
976 | _FMT_GIF: 'image/gif', | |
|
977 | } | |
|
999 | 978 | |
|
1000 | 979 | def __init__(self, data=None, url=None, filename=None, format=None, |
|
1001 | 980 | embed=None, width=None, height=None, retina=False, |
@@ -1097,12 +1076,15 b' class Image(DisplayObject):' | |||
|
1097 | 1076 | if format.lower() == 'jpg': |
|
1098 | 1077 | # jpg->jpeg |
|
1099 | 1078 | format = self._FMT_JPEG |
|
1100 | ||
|
1079 | ||
|
1101 | 1080 | self.format = format.lower() |
|
1102 | 1081 | self.embed = embed if embed is not None else (url is None) |
|
1103 | 1082 | |
|
1104 | 1083 | if self.embed and self.format not in self._ACCEPTABLE_EMBEDDINGS: |
|
1105 | 1084 | raise ValueError("Cannot embed the '%s' image format" % (self.format)) |
|
1085 | if self.embed: | |
|
1086 | self._mimetype = self._MIMETYPES.get(self.format) | |
|
1087 | ||
|
1106 | 1088 | self.width = width |
|
1107 | 1089 | self.height = height |
|
1108 | 1090 | self.retina = retina |
@@ -1119,6 +1101,7 b' class Image(DisplayObject):' | |||
|
1119 | 1101 | if retina: |
|
1120 | 1102 | self._retina_shape() |
|
1121 | 1103 | |
|
1104 | ||
|
1122 | 1105 | def _retina_shape(self): |
|
1123 | 1106 | """load pixel-doubled width and height from image data""" |
|
1124 | 1107 | if not self.embed: |
@@ -1158,7 +1141,21 b' class Image(DisplayObject):' | |||
|
1158 | 1141 | klass=klass, |
|
1159 | 1142 | ) |
|
1160 | 1143 | |
|
1161 | def _data_and_metadata(self): | |
|
1144 | def _repr_mimebundle_(self, include=None, exclude=None): | |
|
1145 | """Return the image as a mimebundle | |
|
1146 | ||
|
1147 | Any new mimetype support should be implemented here. | |
|
1148 | """ | |
|
1149 | if self.embed: | |
|
1150 | mimetype = self._mimetype | |
|
1151 | data, metadata = self._data_and_metadata(always_both=True) | |
|
1152 | if metadata: | |
|
1153 | metadata = {mimetype: metadata} | |
|
1154 | return {mimetype: data}, metadata | |
|
1155 | else: | |
|
1156 | return {'text/html': self._repr_html_()} | |
|
1157 | ||
|
1158 | def _data_and_metadata(self, always_both=False): | |
|
1162 | 1159 | """shortcut for returning metadata with shape information, if defined""" |
|
1163 | 1160 | md = {} |
|
1164 | 1161 | if self.metadata: |
@@ -1169,7 +1166,7 b' class Image(DisplayObject):' | |||
|
1169 | 1166 | md['height'] = self.height |
|
1170 | 1167 | if self.unconfined: |
|
1171 | 1168 | md['unconfined'] = self.unconfined |
|
1172 | if md: | |
|
1169 | if md or always_both: | |
|
1173 | 1170 | return self.data, md |
|
1174 | 1171 | else: |
|
1175 | 1172 | return self.data |
@@ -1179,16 +1176,13 b' class Image(DisplayObject):' | |||
|
1179 | 1176 | return self._data_and_metadata() |
|
1180 | 1177 | |
|
1181 | 1178 | def _repr_jpeg_(self): |
|
1182 |
if self.embed and |
|
|
1183 | return self._data_and_metadata() | |
|
1184 | ||
|
1185 | def _repr_gif_(self): | |
|
1186 | if self.embed and self.format == self._FMT_GIF: | |
|
1179 | if self.embed and self.format == self._FMT_JPEG: | |
|
1187 | 1180 | return self._data_and_metadata() |
|
1188 | 1181 | |
|
1189 | 1182 | def _find_ext(self, s): |
|
1190 | 1183 | return s.split('.')[-1].lower() |
|
1191 | 1184 | |
|
1185 | ||
|
1192 | 1186 | class Video(DisplayObject): |
|
1193 | 1187 | |
|
1194 | 1188 | def __init__(self, data=None, url=None, filename=None, embed=False, mimetype=None): |
@@ -1287,15 +1281,6 b' class Video(DisplayObject):' | |||
|
1287 | 1281 | # TODO |
|
1288 | 1282 | pass |
|
1289 | 1283 | |
|
1290 | def _repr_png_(self): | |
|
1291 | # TODO | |
|
1292 | pass | |
|
1293 | def _repr_jpeg_(self): | |
|
1294 | # TODO | |
|
1295 | pass | |
|
1296 | def _repr_gif_(self): | |
|
1297 | # TODO | |
|
1298 | pass | |
|
1299 | 1284 | |
|
1300 | 1285 | def clear_output(wait=False): |
|
1301 | 1286 | """Clear the output of the current cell receiving output. |
@@ -74,7 +74,6 b' class DisplayFormatter(Configurable):' | |||
|
74 | 74 | MarkdownFormatter, |
|
75 | 75 | SVGFormatter, |
|
76 | 76 | PNGFormatter, |
|
77 | GIFFormatter, | |
|
78 | 77 | PDFFormatter, |
|
79 | 78 | JPEGFormatter, |
|
80 | 79 | LatexFormatter, |
@@ -780,24 +779,6 b' class JPEGFormatter(BaseFormatter):' | |||
|
780 | 779 | _return_type = (bytes, str) |
|
781 | 780 | |
|
782 | 781 | |
|
783 | class GIFFormatter(BaseFormatter): | |
|
784 | """A PNG formatter. | |
|
785 | ||
|
786 | To define the callables that compute the GIF representation of your | |
|
787 | objects, define a :meth:`_repr_gif_` method or use the :meth:`for_type` | |
|
788 | or :meth:`for_type_by_name` methods to register functions that handle | |
|
789 | this. | |
|
790 | ||
|
791 | The return value of this formatter should be raw GIF data, *not* | |
|
792 | base64 encoded. | |
|
793 | """ | |
|
794 | format_type = Unicode('image/gif') | |
|
795 | ||
|
796 | print_method = ObjectName('_repr_gif_') | |
|
797 | ||
|
798 | _return_type = (bytes, str) | |
|
799 | ||
|
800 | ||
|
801 | 782 | class LatexFormatter(BaseFormatter): |
|
802 | 783 | """A LaTeX formatter. |
|
803 | 784 | |
@@ -977,10 +958,7 b' class MimeBundleFormatter(BaseFormatter):' | |||
|
977 | 958 | method = get_real_method(obj, self.print_method) |
|
978 | 959 | |
|
979 | 960 | if method is not None: |
|
980 | d = {} | |
|
981 | d['include'] = include | |
|
982 | d['exclude'] = exclude | |
|
983 | return method(**d) | |
|
961 | return method(include=include, exclude=exclude) | |
|
984 | 962 | return None |
|
985 | 963 | else: |
|
986 | 964 | return None |
@@ -992,7 +970,6 b' FormatterABC.register(HTMLFormatter)' | |||
|
992 | 970 | FormatterABC.register(MarkdownFormatter) |
|
993 | 971 | FormatterABC.register(SVGFormatter) |
|
994 | 972 | FormatterABC.register(PNGFormatter) |
|
995 | FormatterABC.register(GIFFormatter) | |
|
996 | 973 | FormatterABC.register(PDFFormatter) |
|
997 | 974 | FormatterABC.register(JPEGFormatter) |
|
998 | 975 | FormatterABC.register(LatexFormatter) |
@@ -1007,19 +984,6 b' def format_display_data(obj, include=None, exclude=None):' | |||
|
1007 | 984 | |
|
1008 | 985 | By default all format types will be computed. |
|
1009 | 986 | |
|
1010 | The following MIME types are currently implemented: | |
|
1011 | ||
|
1012 | * text/plain | |
|
1013 | * text/html | |
|
1014 | * text/markdown | |
|
1015 | * text/latex | |
|
1016 | * application/json | |
|
1017 | * application/javascript | |
|
1018 | * application/pdf | |
|
1019 | * image/png | |
|
1020 | * image/jpeg | |
|
1021 | * image/svg+xml | |
|
1022 | ||
|
1023 | 987 | Parameters |
|
1024 | 988 | ---------- |
|
1025 | 989 | obj : object |
@@ -32,6 +32,15 b' def test_image_size():' | |||
|
32 | 32 | nt.assert_equal(u'<img src="%s" class="unconfined"/>' % (thisurl), img._repr_html_()) |
|
33 | 33 | |
|
34 | 34 | |
|
35 | def test_image_mimes(): | |
|
36 | fmt = get_ipython().display_formatter.format | |
|
37 | for format in display.Image._ACCEPTABLE_EMBEDDINGS: | |
|
38 | mime = display.Image._MIMETYPES[format] | |
|
39 | img = display.Image(b'garbage', format=format) | |
|
40 | data, metadata = fmt(img) | |
|
41 | nt.assert_equal(sorted(data), sorted([mime, 'text/plain'])) | |
|
42 | ||
|
43 | ||
|
35 | 44 | def test_geojson(): |
|
36 | 45 | |
|
37 | 46 | gj = display.GeoJSON(data={ |
@@ -361,3 +370,4 b' def test_display_handle():' | |||
|
361 | 370 | }, |
|
362 | 371 | 'update': True, |
|
363 | 372 | }) |
|
373 |
@@ -30,7 +30,10 b' class RichOutput(object):' | |||
|
30 | 30 | return data, self.metadata[mime] |
|
31 | 31 | else: |
|
32 | 32 | return data |
|
33 | ||
|
33 | ||
|
34 | def _repr_mimebundle_(self, include=None, exclude=None): | |
|
35 | return self.data, self.metadata | |
|
36 | ||
|
34 | 37 | def _repr_html_(self): |
|
35 | 38 | return self._repr_mime_("text/html") |
|
36 | 39 | |
@@ -48,9 +51,6 b' class RichOutput(object):' | |||
|
48 | 51 | |
|
49 | 52 | def _repr_jpeg_(self): |
|
50 | 53 | return self._repr_mime_("image/jpeg") |
|
51 | ||
|
52 | def _repr_gif_(self): | |
|
53 | return self._repr_mime_("image/gif") | |
|
54 | 54 | |
|
55 | 55 | def _repr_svg_(self): |
|
56 | 56 | return self._repr_mime_("image/svg+xml") |
General Comments 0
You need to be logged in to leave comments.
Login now