##// END OF EJS Templates
fix explicit Image format override...
Min RK -
Show More
@@ -1,967 +1,977 b''
1 1 # -*- coding: utf-8 -*-
2 2 """Top-level display functions for displaying object in different formats."""
3 3
4 4 # Copyright (c) IPython Development Team.
5 5 # Distributed under the terms of the Modified BSD License.
6 6
7 7 from __future__ import print_function
8 8
9 9 import json
10 10 import mimetypes
11 11 import os
12 12 import struct
13 13 import warnings
14 14
15 15 from IPython.core.formatters import _safe_get_formatter_method
16 16 from IPython.utils.py3compat import (string_types, cast_bytes_py2, cast_unicode,
17 17 unicode_type)
18 18 from IPython.testing.skipdoctest import skip_doctest
19 19
20 20 __all__ = ['display', 'display_pretty', 'display_html', 'display_markdown',
21 21 'display_svg', 'display_png', 'display_jpeg', 'display_latex', 'display_json',
22 22 'display_javascript', 'display_pdf', 'DisplayObject', 'TextDisplayObject',
23 23 'Pretty', 'HTML', 'Markdown', 'Math', 'Latex', 'SVG', 'JSON', 'Javascript',
24 24 'Image', 'clear_output', 'set_matplotlib_formats', 'set_matplotlib_close',
25 25 'publish_display_data']
26 26
27 27 #-----------------------------------------------------------------------------
28 28 # utility functions
29 29 #-----------------------------------------------------------------------------
30 30
31 31 def _safe_exists(path):
32 32 """Check path, but don't let exceptions raise"""
33 33 try:
34 34 return os.path.exists(path)
35 35 except Exception:
36 36 return False
37 37
38 38 def _merge(d1, d2):
39 39 """Like update, but merges sub-dicts instead of clobbering at the top level.
40 40
41 41 Updates d1 in-place
42 42 """
43 43
44 44 if not isinstance(d2, dict) or not isinstance(d1, dict):
45 45 return d2
46 46 for key, value in d2.items():
47 47 d1[key] = _merge(d1.get(key), value)
48 48 return d1
49 49
50 50 def _display_mimetype(mimetype, objs, raw=False, metadata=None):
51 51 """internal implementation of all display_foo methods
52 52
53 53 Parameters
54 54 ----------
55 55 mimetype : str
56 56 The mimetype to be published (e.g. 'image/png')
57 57 objs : tuple of objects
58 58 The Python objects to display, or if raw=True raw text data to
59 59 display.
60 60 raw : bool
61 61 Are the data objects raw data or Python objects that need to be
62 62 formatted before display? [default: False]
63 63 metadata : dict (optional)
64 64 Metadata to be associated with the specific mimetype output.
65 65 """
66 66 if metadata:
67 67 metadata = {mimetype: metadata}
68 68 if raw:
69 69 # turn list of pngdata into list of { 'image/png': pngdata }
70 70 objs = [ {mimetype: obj} for obj in objs ]
71 71 display(*objs, raw=raw, metadata=metadata, include=[mimetype])
72 72
73 73 #-----------------------------------------------------------------------------
74 74 # Main functions
75 75 #-----------------------------------------------------------------------------
76 76
77 77 def publish_display_data(data, metadata=None, source=None):
78 78 """Publish data and metadata to all frontends.
79 79
80 80 See the ``display_data`` message in the messaging documentation for
81 81 more details about this message type.
82 82
83 83 The following MIME types are currently implemented:
84 84
85 85 * text/plain
86 86 * text/html
87 87 * text/markdown
88 88 * text/latex
89 89 * application/json
90 90 * application/javascript
91 91 * image/png
92 92 * image/jpeg
93 93 * image/svg+xml
94 94
95 95 Parameters
96 96 ----------
97 97 data : dict
98 98 A dictionary having keys that are valid MIME types (like
99 99 'text/plain' or 'image/svg+xml') and values that are the data for
100 100 that MIME type. The data itself must be a JSON'able data
101 101 structure. Minimally all data should have the 'text/plain' data,
102 102 which can be displayed by all frontends. If more than the plain
103 103 text is given, it is up to the frontend to decide which
104 104 representation to use.
105 105 metadata : dict
106 106 A dictionary for metadata related to the data. This can contain
107 107 arbitrary key, value pairs that frontends can use to interpret
108 108 the data. mime-type keys matching those in data can be used
109 109 to specify metadata about particular representations.
110 110 source : str, deprecated
111 111 Unused.
112 112 """
113 113 from IPython.core.interactiveshell import InteractiveShell
114 114 InteractiveShell.instance().display_pub.publish(
115 115 data=data,
116 116 metadata=metadata,
117 117 )
118 118
119 119 def display(*objs, **kwargs):
120 120 """Display a Python object in all frontends.
121 121
122 122 By default all representations will be computed and sent to the frontends.
123 123 Frontends can decide which representation is used and how.
124 124
125 125 Parameters
126 126 ----------
127 127 objs : tuple of objects
128 128 The Python objects to display.
129 129 raw : bool, optional
130 130 Are the objects to be displayed already mimetype-keyed dicts of raw display data,
131 131 or Python objects that need to be formatted before display? [default: False]
132 132 include : list or tuple, optional
133 133 A list of format type strings (MIME types) to include in the
134 134 format data dict. If this is set *only* the format types included
135 135 in this list will be computed.
136 136 exclude : list or tuple, optional
137 137 A list of format type strings (MIME types) to exclude in the format
138 138 data dict. If this is set all format types will be computed,
139 139 except for those included in this argument.
140 140 metadata : dict, optional
141 141 A dictionary of metadata to associate with the output.
142 142 mime-type keys in this dictionary will be associated with the individual
143 143 representation formats, if they exist.
144 144 """
145 145 raw = kwargs.get('raw', False)
146 146 include = kwargs.get('include')
147 147 exclude = kwargs.get('exclude')
148 148 metadata = kwargs.get('metadata')
149 149
150 150 from IPython.core.interactiveshell import InteractiveShell
151 151
152 152 if not raw:
153 153 format = InteractiveShell.instance().display_formatter.format
154 154
155 155 for obj in objs:
156 156 if raw:
157 157 publish_display_data(data=obj, metadata=metadata)
158 158 else:
159 159 format_dict, md_dict = format(obj, include=include, exclude=exclude)
160 160 if not format_dict:
161 161 # nothing to display (e.g. _ipython_display_ took over)
162 162 continue
163 163 if metadata:
164 164 # kwarg-specified metadata gets precedence
165 165 _merge(md_dict, metadata)
166 166 publish_display_data(data=format_dict, metadata=md_dict)
167 167
168 168
169 169 def display_pretty(*objs, **kwargs):
170 170 """Display the pretty (default) representation of an object.
171 171
172 172 Parameters
173 173 ----------
174 174 objs : tuple of objects
175 175 The Python objects to display, or if raw=True raw text data to
176 176 display.
177 177 raw : bool
178 178 Are the data objects raw data or Python objects that need to be
179 179 formatted before display? [default: False]
180 180 metadata : dict (optional)
181 181 Metadata to be associated with the specific mimetype output.
182 182 """
183 183 _display_mimetype('text/plain', objs, **kwargs)
184 184
185 185
186 186 def display_html(*objs, **kwargs):
187 187 """Display the HTML representation of an object.
188 188
189 189 Parameters
190 190 ----------
191 191 objs : tuple of objects
192 192 The Python objects to display, or if raw=True raw HTML data to
193 193 display.
194 194 raw : bool
195 195 Are the data objects raw data or Python objects that need to be
196 196 formatted before display? [default: False]
197 197 metadata : dict (optional)
198 198 Metadata to be associated with the specific mimetype output.
199 199 """
200 200 _display_mimetype('text/html', objs, **kwargs)
201 201
202 202
203 203 def display_markdown(*objs, **kwargs):
204 204 """Displays the Markdown representation of an object.
205 205
206 206 Parameters
207 207 ----------
208 208 objs : tuple of objects
209 209 The Python objects to display, or if raw=True raw markdown data to
210 210 display.
211 211 raw : bool
212 212 Are the data objects raw data or Python objects that need to be
213 213 formatted before display? [default: False]
214 214 metadata : dict (optional)
215 215 Metadata to be associated with the specific mimetype output.
216 216 """
217 217
218 218 _display_mimetype('text/markdown', objs, **kwargs)
219 219
220 220
221 221 def display_svg(*objs, **kwargs):
222 222 """Display the SVG representation of an object.
223 223
224 224 Parameters
225 225 ----------
226 226 objs : tuple of objects
227 227 The Python objects to display, or if raw=True raw svg data to
228 228 display.
229 229 raw : bool
230 230 Are the data objects raw data or Python objects that need to be
231 231 formatted before display? [default: False]
232 232 metadata : dict (optional)
233 233 Metadata to be associated with the specific mimetype output.
234 234 """
235 235 _display_mimetype('image/svg+xml', objs, **kwargs)
236 236
237 237
238 238 def display_png(*objs, **kwargs):
239 239 """Display the PNG representation of an object.
240 240
241 241 Parameters
242 242 ----------
243 243 objs : tuple of objects
244 244 The Python objects to display, or if raw=True raw png data to
245 245 display.
246 246 raw : bool
247 247 Are the data objects raw data or Python objects that need to be
248 248 formatted before display? [default: False]
249 249 metadata : dict (optional)
250 250 Metadata to be associated with the specific mimetype output.
251 251 """
252 252 _display_mimetype('image/png', objs, **kwargs)
253 253
254 254
255 255 def display_jpeg(*objs, **kwargs):
256 256 """Display the JPEG representation of an object.
257 257
258 258 Parameters
259 259 ----------
260 260 objs : tuple of objects
261 261 The Python objects to display, or if raw=True raw JPEG data to
262 262 display.
263 263 raw : bool
264 264 Are the data objects raw data or Python objects that need to be
265 265 formatted before display? [default: False]
266 266 metadata : dict (optional)
267 267 Metadata to be associated with the specific mimetype output.
268 268 """
269 269 _display_mimetype('image/jpeg', objs, **kwargs)
270 270
271 271
272 272 def display_latex(*objs, **kwargs):
273 273 """Display the LaTeX representation of an object.
274 274
275 275 Parameters
276 276 ----------
277 277 objs : tuple of objects
278 278 The Python objects to display, or if raw=True raw latex data to
279 279 display.
280 280 raw : bool
281 281 Are the data objects raw data or Python objects that need to be
282 282 formatted before display? [default: False]
283 283 metadata : dict (optional)
284 284 Metadata to be associated with the specific mimetype output.
285 285 """
286 286 _display_mimetype('text/latex', objs, **kwargs)
287 287
288 288
289 289 def display_json(*objs, **kwargs):
290 290 """Display the JSON representation of an object.
291 291
292 292 Note that not many frontends support displaying JSON.
293 293
294 294 Parameters
295 295 ----------
296 296 objs : tuple of objects
297 297 The Python objects to display, or if raw=True raw json data to
298 298 display.
299 299 raw : bool
300 300 Are the data objects raw data or Python objects that need to be
301 301 formatted before display? [default: False]
302 302 metadata : dict (optional)
303 303 Metadata to be associated with the specific mimetype output.
304 304 """
305 305 _display_mimetype('application/json', objs, **kwargs)
306 306
307 307
308 308 def display_javascript(*objs, **kwargs):
309 309 """Display the Javascript representation of an object.
310 310
311 311 Parameters
312 312 ----------
313 313 objs : tuple of objects
314 314 The Python objects to display, or if raw=True raw javascript data to
315 315 display.
316 316 raw : bool
317 317 Are the data objects raw data or Python objects that need to be
318 318 formatted before display? [default: False]
319 319 metadata : dict (optional)
320 320 Metadata to be associated with the specific mimetype output.
321 321 """
322 322 _display_mimetype('application/javascript', objs, **kwargs)
323 323
324 324
325 325 def display_pdf(*objs, **kwargs):
326 326 """Display the PDF representation of an object.
327 327
328 328 Parameters
329 329 ----------
330 330 objs : tuple of objects
331 331 The Python objects to display, or if raw=True raw javascript data to
332 332 display.
333 333 raw : bool
334 334 Are the data objects raw data or Python objects that need to be
335 335 formatted before display? [default: False]
336 336 metadata : dict (optional)
337 337 Metadata to be associated with the specific mimetype output.
338 338 """
339 339 _display_mimetype('application/pdf', objs, **kwargs)
340 340
341 341
342 342 #-----------------------------------------------------------------------------
343 343 # Smart classes
344 344 #-----------------------------------------------------------------------------
345 345
346 346
347 347 class DisplayObject(object):
348 348 """An object that wraps data to be displayed."""
349 349
350 350 _read_flags = 'r'
351 351 _show_mem_addr = False
352 352
353 353 def __init__(self, data=None, url=None, filename=None):
354 354 """Create a display object given raw data.
355 355
356 356 When this object is returned by an expression or passed to the
357 357 display function, it will result in the data being displayed
358 358 in the frontend. The MIME type of the data should match the
359 359 subclasses used, so the Png subclass should be used for 'image/png'
360 360 data. If the data is a URL, the data will first be downloaded
361 361 and then displayed. If
362 362
363 363 Parameters
364 364 ----------
365 365 data : unicode, str or bytes
366 366 The raw data or a URL or file to load the data from
367 367 url : unicode
368 368 A URL to download the data from.
369 369 filename : unicode
370 370 Path to a local file to load the data from.
371 371 """
372 372 if data is not None and isinstance(data, string_types):
373 373 if data.startswith('http') and url is None:
374 374 url = data
375 375 filename = None
376 376 data = None
377 377 elif _safe_exists(data) and filename is None:
378 378 url = None
379 379 filename = data
380 380 data = None
381 381
382 382 self.data = data
383 383 self.url = url
384 384 self.filename = None if filename is None else unicode_type(filename)
385 385
386 386 self.reload()
387 387 self._check_data()
388 388
389 389 def __repr__(self):
390 390 if not self._show_mem_addr:
391 391 cls = self.__class__
392 392 r = "<%s.%s object>" % (cls.__module__, cls.__name__)
393 393 else:
394 394 r = super(DisplayObject, self).__repr__()
395 395 return r
396 396
397 397 def _check_data(self):
398 398 """Override in subclasses if there's something to check."""
399 399 pass
400 400
401 401 def reload(self):
402 402 """Reload the raw data from file or URL."""
403 403 if self.filename is not None:
404 404 with open(self.filename, self._read_flags) as f:
405 405 self.data = f.read()
406 406 elif self.url is not None:
407 407 try:
408 408 try:
409 409 from urllib.request import urlopen # Py3
410 410 except ImportError:
411 411 from urllib2 import urlopen
412 412 response = urlopen(self.url)
413 413 self.data = response.read()
414 414 # extract encoding from header, if there is one:
415 415 encoding = None
416 416 for sub in response.headers['content-type'].split(';'):
417 417 sub = sub.strip()
418 418 if sub.startswith('charset'):
419 419 encoding = sub.split('=')[-1].strip()
420 420 break
421 421 # decode data, if an encoding was specified
422 422 if encoding:
423 423 self.data = self.data.decode(encoding, 'replace')
424 424 except:
425 425 self.data = None
426 426
427 427 class TextDisplayObject(DisplayObject):
428 428 """Validate that display data is text"""
429 429 def _check_data(self):
430 430 if self.data is not None and not isinstance(self.data, string_types):
431 431 raise TypeError("%s expects text, not %r" % (self.__class__.__name__, self.data))
432 432
433 433 class Pretty(TextDisplayObject):
434 434
435 435 def _repr_pretty_(self):
436 436 return self.data
437 437
438 438
439 439 class HTML(TextDisplayObject):
440 440
441 441 def _repr_html_(self):
442 442 return self.data
443 443
444 444 def __html__(self):
445 445 """
446 446 This method exists to inform other HTML-using modules (e.g. Markupsafe,
447 447 htmltag, etc) that this object is HTML and does not need things like
448 448 special characters (<>&) escaped.
449 449 """
450 450 return self._repr_html_()
451 451
452 452
453 453 class Markdown(TextDisplayObject):
454 454
455 455 def _repr_markdown_(self):
456 456 return self.data
457 457
458 458
459 459 class Math(TextDisplayObject):
460 460
461 461 def _repr_latex_(self):
462 462 s = self.data.strip('$')
463 463 return "$$%s$$" % s
464 464
465 465
466 466 class Latex(TextDisplayObject):
467 467
468 468 def _repr_latex_(self):
469 469 return self.data
470 470
471 471
472 472 class SVG(DisplayObject):
473 473
474 474 # wrap data in a property, which extracts the <svg> tag, discarding
475 475 # document headers
476 476 _data = None
477 477
478 478 @property
479 479 def data(self):
480 480 return self._data
481 481
482 482 @data.setter
483 483 def data(self, svg):
484 484 if svg is None:
485 485 self._data = None
486 486 return
487 487 # parse into dom object
488 488 from xml.dom import minidom
489 489 svg = cast_bytes_py2(svg)
490 490 x = minidom.parseString(svg)
491 491 # get svg tag (should be 1)
492 492 found_svg = x.getElementsByTagName('svg')
493 493 if found_svg:
494 494 svg = found_svg[0].toxml()
495 495 else:
496 496 # fallback on the input, trust the user
497 497 # but this is probably an error.
498 498 pass
499 499 svg = cast_unicode(svg)
500 500 self._data = svg
501 501
502 502 def _repr_svg_(self):
503 503 return self.data
504 504
505 505
506 506 class JSON(DisplayObject):
507 507 """JSON expects a JSON-able dict or list
508 508
509 509 not an already-serialized JSON string.
510 510
511 511 Scalar types (None, number, string) are not allowed, only dict or list containers.
512 512 """
513 513 # wrap data in a property, which warns about passing already-serialized JSON
514 514 _data = None
515 515 def _check_data(self):
516 516 if self.data is not None and not isinstance(self.data, (dict, list)):
517 517 raise TypeError("%s expects JSONable dict or list, not %r" % (self.__class__.__name__, self.data))
518 518
519 519 @property
520 520 def data(self):
521 521 return self._data
522 522
523 523 @data.setter
524 524 def data(self, data):
525 525 if isinstance(data, string_types):
526 526 warnings.warn("JSON expects JSONable dict or list, not JSON strings")
527 527 data = json.loads(data)
528 528 self._data = data
529 529
530 530 def _repr_json_(self):
531 531 return self.data
532 532
533 533 css_t = """$("head").append($("<link/>").attr({
534 534 rel: "stylesheet",
535 535 type: "text/css",
536 536 href: "%s"
537 537 }));
538 538 """
539 539
540 540 lib_t1 = """$.getScript("%s", function () {
541 541 """
542 542 lib_t2 = """});
543 543 """
544 544
545 545 class Javascript(TextDisplayObject):
546 546
547 547 def __init__(self, data=None, url=None, filename=None, lib=None, css=None):
548 548 """Create a Javascript display object given raw data.
549 549
550 550 When this object is returned by an expression or passed to the
551 551 display function, it will result in the data being displayed
552 552 in the frontend. If the data is a URL, the data will first be
553 553 downloaded and then displayed.
554 554
555 555 In the Notebook, the containing element will be available as `element`,
556 556 and jQuery will be available. Content appended to `element` will be
557 557 visible in the output area.
558 558
559 559 Parameters
560 560 ----------
561 561 data : unicode, str or bytes
562 562 The Javascript source code or a URL to download it from.
563 563 url : unicode
564 564 A URL to download the data from.
565 565 filename : unicode
566 566 Path to a local file to load the data from.
567 567 lib : list or str
568 568 A sequence of Javascript library URLs to load asynchronously before
569 569 running the source code. The full URLs of the libraries should
570 570 be given. A single Javascript library URL can also be given as a
571 571 string.
572 572 css: : list or str
573 573 A sequence of css files to load before running the source code.
574 574 The full URLs of the css files should be given. A single css URL
575 575 can also be given as a string.
576 576 """
577 577 if isinstance(lib, string_types):
578 578 lib = [lib]
579 579 elif lib is None:
580 580 lib = []
581 581 if isinstance(css, string_types):
582 582 css = [css]
583 583 elif css is None:
584 584 css = []
585 585 if not isinstance(lib, (list,tuple)):
586 586 raise TypeError('expected sequence, got: %r' % lib)
587 587 if not isinstance(css, (list,tuple)):
588 588 raise TypeError('expected sequence, got: %r' % css)
589 589 self.lib = lib
590 590 self.css = css
591 591 super(Javascript, self).__init__(data=data, url=url, filename=filename)
592 592
593 593 def _repr_javascript_(self):
594 594 r = ''
595 595 for c in self.css:
596 596 r += css_t % c
597 597 for l in self.lib:
598 598 r += lib_t1 % l
599 599 r += self.data
600 600 r += lib_t2*len(self.lib)
601 601 return r
602 602
603 603 # constants for identifying png/jpeg data
604 604 _PNG = b'\x89PNG\r\n\x1a\n'
605 605 _JPEG = b'\xff\xd8'
606 606
607 607 def _pngxy(data):
608 608 """read the (width, height) from a PNG header"""
609 609 ihdr = data.index(b'IHDR')
610 610 # next 8 bytes are width/height
611 611 w4h4 = data[ihdr+4:ihdr+12]
612 612 return struct.unpack('>ii', w4h4)
613 613
614 614 def _jpegxy(data):
615 615 """read the (width, height) from a JPEG header"""
616 616 # adapted from http://www.64lines.com/jpeg-width-height
617 617
618 618 idx = 4
619 619 while True:
620 620 block_size = struct.unpack('>H', data[idx:idx+2])[0]
621 621 idx = idx + block_size
622 622 if data[idx:idx+2] == b'\xFF\xC0':
623 623 # found Start of Frame
624 624 iSOF = idx
625 625 break
626 626 else:
627 627 # read another block
628 628 idx += 2
629 629
630 630 h, w = struct.unpack('>HH', data[iSOF+5:iSOF+9])
631 631 return w, h
632 632
633 633 class Image(DisplayObject):
634 634
635 635 _read_flags = 'rb'
636 636 _FMT_JPEG = u'jpeg'
637 637 _FMT_PNG = u'png'
638 638 _ACCEPTABLE_EMBEDDINGS = [_FMT_JPEG, _FMT_PNG]
639 639
640 def __init__(self, data=None, url=None, filename=None, format=u'png',
640 def __init__(self, data=None, url=None, filename=None, format=None,
641 641 embed=None, width=None, height=None, retina=False,
642 642 unconfined=False, metadata=None):
643 643 """Create a PNG/JPEG image object given raw data.
644 644
645 645 When this object is returned by an input cell or passed to the
646 646 display function, it will result in the image being displayed
647 647 in the frontend.
648 648
649 649 Parameters
650 650 ----------
651 651 data : unicode, str or bytes
652 652 The raw image data or a URL or filename to load the data from.
653 653 This always results in embedded image data.
654 654 url : unicode
655 655 A URL to download the data from. If you specify `url=`,
656 656 the image data will not be embedded unless you also specify `embed=True`.
657 657 filename : unicode
658 658 Path to a local file to load the data from.
659 659 Images from a file are always embedded.
660 660 format : unicode
661 661 The format of the image data (png/jpeg/jpg). If a filename or URL is given
662 662 for format will be inferred from the filename extension.
663 663 embed : bool
664 664 Should the image data be embedded using a data URI (True) or be
665 665 loaded using an <img> tag. Set this to True if you want the image
666 666 to be viewable later with no internet connection in the notebook.
667 667
668 668 Default is `True`, unless the keyword argument `url` is set, then
669 669 default value is `False`.
670 670
671 671 Note that QtConsole is not able to display images if `embed` is set to `False`
672 672 width : int
673 673 Width to which to constrain the image in html
674 674 height : int
675 675 Height to which to constrain the image in html
676 676 retina : bool
677 677 Automatically set the width and height to half of the measured
678 678 width and height.
679 679 This only works for embedded images because it reads the width/height
680 680 from image data.
681 681 For non-embedded images, you can just set the desired display width
682 682 and height directly.
683 683 unconfined: bool
684 684 Set unconfined=True to disable max-width confinement of the image.
685 685 metadata: dict
686 686 Specify extra metadata to attach to the image.
687 687
688 688 Examples
689 689 --------
690 690 # embedded image data, works in qtconsole and notebook
691 691 # when passed positionally, the first arg can be any of raw image data,
692 692 # a URL, or a filename from which to load image data.
693 693 # The result is always embedding image data for inline images.
694 694 Image('http://www.google.fr/images/srpr/logo3w.png')
695 695 Image('/path/to/image.jpg')
696 696 Image(b'RAW_PNG_DATA...')
697 697
698 698 # Specifying Image(url=...) does not embed the image data,
699 699 # it only generates `<img>` tag with a link to the source.
700 700 # This will not work in the qtconsole or offline.
701 701 Image(url='http://www.google.fr/images/srpr/logo3w.png')
702 702
703 703 """
704 704 if filename is not None:
705 705 ext = self._find_ext(filename)
706 706 elif url is not None:
707 707 ext = self._find_ext(url)
708 708 elif data is None:
709 709 raise ValueError("No image data found. Expecting filename, url, or data.")
710 710 elif isinstance(data, string_types) and (
711 711 data.startswith('http') or _safe_exists(data)
712 712 ):
713 713 ext = self._find_ext(data)
714 714 else:
715 715 ext = None
716 716
717 if ext is not None:
718 format = ext.lower()
719 if ext == u'jpg' or ext == u'jpeg':
720 format = self._FMT_JPEG
721 if ext == u'png':
722 format = self._FMT_PNG
723 elif isinstance(data, bytes) and format == 'png':
724 # infer image type from image data header,
725 # only if format might not have been specified.
726 if data[:2] == _JPEG:
727 format = 'jpeg'
717 if format is None:
718 if ext is not None:
719 if ext == u'jpg' or ext == u'jpeg':
720 format = self._FMT_JPEG
721 if ext == u'png':
722 format = self._FMT_PNG
723 else:
724 format = ext.lower()
725 elif isinstance(data, bytes):
726 # infer image type from image data header,
727 # only if format has not been specified.
728 if data[:2] == _JPEG:
729 format = self._FMT_JPEG
730
731 if format.lower() == 'jpg':
732 # jpg->jpeg
733 format = self._FMT_JPEG
734
735 # failed to detect format, default png
736 if format is None:
737 format = 'png'
728 738
729 739 self.format = unicode_type(format).lower()
730 740 self.embed = embed if embed is not None else (url is None)
731 741
732 742 if self.embed and self.format not in self._ACCEPTABLE_EMBEDDINGS:
733 743 raise ValueError("Cannot embed the '%s' image format" % (self.format))
734 744 self.width = width
735 745 self.height = height
736 746 self.retina = retina
737 747 self.unconfined = unconfined
738 748 self.metadata = metadata
739 749 super(Image, self).__init__(data=data, url=url, filename=filename)
740 750
741 751 if retina:
742 752 self._retina_shape()
743 753
744 754 def _retina_shape(self):
745 755 """load pixel-doubled width and height from image data"""
746 756 if not self.embed:
747 757 return
748 758 if self.format == 'png':
749 759 w, h = _pngxy(self.data)
750 760 elif self.format == 'jpeg':
751 761 w, h = _jpegxy(self.data)
752 762 else:
753 763 # retina only supports png
754 764 return
755 765 self.width = w // 2
756 766 self.height = h // 2
757 767
758 768 def reload(self):
759 769 """Reload the raw data from file or URL."""
760 770 if self.embed:
761 771 super(Image,self).reload()
762 772 if self.retina:
763 773 self._retina_shape()
764 774
765 775 def _repr_html_(self):
766 776 if not self.embed:
767 777 width = height = klass = ''
768 778 if self.width:
769 779 width = ' width="%d"' % self.width
770 780 if self.height:
771 781 height = ' height="%d"' % self.height
772 782 if self.unconfined:
773 783 klass = ' class="unconfined"'
774 784 return u'<img src="{url}"{width}{height}{klass}/>'.format(
775 785 url=self.url,
776 786 width=width,
777 787 height=height,
778 788 klass=klass,
779 789 )
780 790
781 791 def _data_and_metadata(self):
782 792 """shortcut for returning metadata with shape information, if defined"""
783 793 md = {}
784 794 if self.width:
785 795 md['width'] = self.width
786 796 if self.height:
787 797 md['height'] = self.height
788 798 if self.unconfined:
789 799 md['unconfined'] = self.unconfined
790 800 if self.metadata:
791 801 md.update(self.metadata)
792 802 if md:
793 803 return self.data, md
794 804 else:
795 805 return self.data
796 806
797 807 def _repr_png_(self):
798 808 if self.embed and self.format == u'png':
799 809 return self._data_and_metadata()
800 810
801 811 def _repr_jpeg_(self):
802 812 if self.embed and (self.format == u'jpeg' or self.format == u'jpg'):
803 813 return self._data_and_metadata()
804 814
805 815 def _find_ext(self, s):
806 816 return unicode_type(s.split('.')[-1].lower())
807 817
808 818 class Video(DisplayObject):
809 819
810 820 def __init__(self, data=None, url=None, filename=None, embed=None, mimetype=None):
811 821 """Create a video object given raw data or an URL.
812 822
813 823 When this object is returned by an input cell or passed to the
814 824 display function, it will result in the video being displayed
815 825 in the frontend.
816 826
817 827 Parameters
818 828 ----------
819 829 data : unicode, str or bytes
820 830 The raw image data or a URL or filename to load the data from.
821 831 This always results in embedded image data.
822 832 url : unicode
823 833 A URL to download the data from. If you specify `url=`,
824 834 the image data will not be embedded unless you also specify `embed=True`.
825 835 filename : unicode
826 836 Path to a local file to load the data from.
827 837 Videos from a file are always embedded.
828 838 embed : bool
829 839 Should the image data be embedded using a data URI (True) or be
830 840 loaded using an <img> tag. Set this to True if you want the image
831 841 to be viewable later with no internet connection in the notebook.
832 842
833 843 Default is `True`, unless the keyword argument `url` is set, then
834 844 default value is `False`.
835 845
836 846 Note that QtConsole is not able to display images if `embed` is set to `False`
837 847 mimetype: unicode
838 848 Specify the mimetype in case you load in a encoded video.
839 849 Examples
840 850 --------
841 851 Video('https://archive.org/download/Sita_Sings_the_Blues/Sita_Sings_the_Blues_small.mp4')
842 852 Video('path/to/video.mp4')
843 853 Video('path/to/video.mp4', embed=False)
844 854 """
845 855 if url is None and (data.startswith('http') or data.startswith('https')):
846 856 url = data
847 857 data = None
848 858 embed = False
849 859 elif os.path.exists(data):
850 860 filename = data
851 861 data = None
852 862
853 863 self.mimetype = mimetype
854 864 self.embed = embed if embed is not None else (filename is not None)
855 865 super(Video, self).__init__(data=data, url=url, filename=filename)
856 866
857 867 def _repr_html_(self):
858 868 # External URLs and potentially local files are not embedded into the
859 869 # notebook output.
860 870 if not self.embed:
861 871 url = self.url if self.url is not None else self.filename
862 872 output = """<video src="{0}" controls>
863 873 Your browser does not support the <code>video</code> element.
864 874 </video>""".format(url)
865 875 return output
866 876 # Embedded videos uses base64 encoded videos.
867 877 if self.filename is not None:
868 878 mimetypes.init()
869 879 mimetype, encoding = mimetypes.guess_type(self.filename)
870 880
871 881 video = open(self.filename, 'rb').read()
872 882 video_encoded = video.encode('base64')
873 883 else:
874 884 video_encoded = self.data
875 885 mimetype = self.mimetype
876 886 output = """<video controls>
877 887 <source src="data:{0};base64,{1}" type="{0}">
878 888 Your browser does not support the video tag.
879 889 </video>""".format(mimetype, video_encoded)
880 890 return output
881 891
882 892 def reload(self):
883 893 # TODO
884 894 pass
885 895
886 896 def _repr_png_(self):
887 897 # TODO
888 898 pass
889 899 def _repr_jpeg_(self):
890 900 # TODO
891 901 pass
892 902
893 903 def clear_output(wait=False):
894 904 """Clear the output of the current cell receiving output.
895 905
896 906 Parameters
897 907 ----------
898 908 wait : bool [default: false]
899 909 Wait to clear the output until new output is available to replace it."""
900 910 from IPython.core.interactiveshell import InteractiveShell
901 911 if InteractiveShell.initialized():
902 912 InteractiveShell.instance().display_pub.clear_output(wait)
903 913 else:
904 914 from IPython.utils import io
905 915 print('\033[2K\r', file=io.stdout, end='')
906 916 io.stdout.flush()
907 917 print('\033[2K\r', file=io.stderr, end='')
908 918 io.stderr.flush()
909 919
910 920
911 921 @skip_doctest
912 922 def set_matplotlib_formats(*formats, **kwargs):
913 923 """Select figure formats for the inline backend. Optionally pass quality for JPEG.
914 924
915 925 For example, this enables PNG and JPEG output with a JPEG quality of 90%::
916 926
917 927 In [1]: set_matplotlib_formats('png', 'jpeg', quality=90)
918 928
919 929 To set this in your config files use the following::
920 930
921 931 c.InlineBackend.figure_formats = {'png', 'jpeg'}
922 932 c.InlineBackend.print_figure_kwargs.update({'quality' : 90})
923 933
924 934 Parameters
925 935 ----------
926 936 *formats : strs
927 937 One or more figure formats to enable: 'png', 'retina', 'jpeg', 'svg', 'pdf'.
928 938 **kwargs :
929 939 Keyword args will be relayed to ``figure.canvas.print_figure``.
930 940 """
931 941 from IPython.core.interactiveshell import InteractiveShell
932 942 from IPython.core.pylabtools import select_figure_formats
933 943 # build kwargs, starting with InlineBackend config
934 944 kw = {}
935 945 from ipykernel.pylab.config import InlineBackend
936 946 cfg = InlineBackend.instance()
937 947 kw.update(cfg.print_figure_kwargs)
938 948 kw.update(**kwargs)
939 949 shell = InteractiveShell.instance()
940 950 select_figure_formats(shell, formats, **kw)
941 951
942 952 @skip_doctest
943 953 def set_matplotlib_close(close=True):
944 954 """Set whether the inline backend closes all figures automatically or not.
945 955
946 956 By default, the inline backend used in the IPython Notebook will close all
947 957 matplotlib figures automatically after each cell is run. This means that
948 958 plots in different cells won't interfere. Sometimes, you may want to make
949 959 a plot in one cell and then refine it in later cells. This can be accomplished
950 960 by::
951 961
952 962 In [1]: set_matplotlib_close(False)
953 963
954 964 To set this in your config files use the following::
955 965
956 966 c.InlineBackend.close_figures = False
957 967
958 968 Parameters
959 969 ----------
960 970 close : bool
961 971 Should all matplotlib figures be automatically closed after each cell is
962 972 run?
963 973 """
964 974 from ipykernel.pylab.config import InlineBackend
965 975 cfg = InlineBackend.instance()
966 976 cfg.close_figures = close
967 977
General Comments 0
You need to be logged in to leave comments. Login now