Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Loading…

handle jpg/jpeg in the qtconsole #1643

Merged
merged 5 commits into from

2 participants

Matthias Bussonnier Min RK
Matthias Bussonnier
Owner

This add jpg/jpeg display in QtConsole, after png has been tried, of course.

IPython/frontend/qt/console/rich_ipython_widget.py
@@ -69,24 +83,38 @@ def _context_menu_make(self, pos):
def _handle_pyout(self, msg):
""" Overridden to handle rich data types, like SVG.
"""
+ def pre_image_append():
Min RK Owner
minrk added a note

This function shouldn't be defined anew every time this is called. Just make it a method.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
IPython/frontend/qt/console/rich_ipython_widget.py
@@ -36,6 +44,12 @@ def __init__(self, *args, **kw):
# Dictionary for resolving document resource names to SVG data.
self._name_to_svg_map = {}
+ # Do we support jpg ?
+ # it seems that sometime jpg support is a plugin of QT, so try to assume
+ # it is not always supported.
+ self._supported_format = map(str, QtGui.QImageReader.supportedImageFormats())
+ self._jpg_supported = 'jpeg' in self._supported_format
Min RK Owner
minrk added a note

There should be no attributes that are not always defined. Make sure this is defined in the class at the top level (_jpg_supported = Bool(False))

Matthias Bussonnier Owner
Carreau added a note

Well, it's true that I can put it at class top level, but I don't see why 'jpeg' in _supported_format can be not defined. and Bool traits would be overkill no ?

Min RK Owner
minrk added a note
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Min RK
Owner

What happens to jpegs during export?

Matthias Bussonnier
Owner

jpeg are converted to png at export time. I thought it was overkill to try to keep the original file format, as well as proposing a full jpeg export. ( who likes jpeg for graphs anyway ? )
Moreover rich_text.py and HtmlExporter are, I think, written to work only with only one function to convert from the <image> tag of the qtconsole to file.

IPython/frontend/qt/console/rich_ipython_widget.py
@@ -65,6 +81,15 @@ def _context_menu_make(self, pos):
#---------------------------------------------------------------------------
# 'BaseFrontendMixin' abstract interface
#---------------------------------------------------------------------------
+ def _pre_image_append(self, msg, prompt_number):
+ """ Append the Out[] prompt and mke the output nicer
Min RK Owner
minrk added a note

mke/make

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Min RK
Owner

one last spelling error, and I think it's ready for merge.

Carreau added some commits
Matthias Bussonnier Carreau handle jpg/jpeg in the qtconsole.
This try to handle both image/jpeg image/jpg mimetype that arrives in
the qtconsole, when QImage support It,
note that image/jpg should never append, but is still supported.

It does not allows the export as html/jpeg. The jpeg will be converted
to png at save time.
c722f75
Matthias Bussonnier Carreau pylinting 51ddac4
Matthias Bussonnier Carreau more robust code
_pre_image_append as method
_jpg_supported as Bool Trait
193559c
Matthias Bussonnier Carreau strip copyright 9e8cfdd
Matthias Bussonnier Carreau do not handle image/jpg 9d7b5df
Matthias Bussonnier
Owner

Thanks, as I rebased on master to avoid recursive merge, I squashed the fix in the commit that introduced the docstring :-)
Should I merge ?

Min RK
Owner

Sure, go for it.

Matthias Bussonnier Carreau merged commit f387e4a into from
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on Apr 25, 2012
  1. Matthias Bussonnier

    handle jpg/jpeg in the qtconsole.

    Carreau authored
    This try to handle both image/jpeg image/jpg mimetype that arrives in
    the qtconsole, when QImage support It,
    note that image/jpg should never append, but is still supported.
    
    It does not allows the export as html/jpeg. The jpeg will be converted
    to png at save time.
  2. Matthias Bussonnier

    pylinting

    Carreau authored
  3. Matthias Bussonnier

    more robust code

    Carreau authored
    _pre_image_append as method
    _jpg_supported as Bool Trait
  4. Matthias Bussonnier

    strip copyright

    Carreau authored
  5. Matthias Bussonnier

    do not handle image/jpg

    Carreau authored
This page is out of date. Refresh to see the latest.
Showing with 58 additions and 19 deletions.
  1. +58 −19 IPython/frontend/qt/console/rich_ipython_widget.py
77 IPython/frontend/qt/console/rich_ipython_widget.py
View
@@ -1,3 +1,11 @@
+#-----------------------------------------------------------------------------
+# Copyright (c) 2010, IPython Development Team.
+#
+# Distributed under the terms of the Modified BSD License.
+#
+# The full license is in the file COPYING.txt, distributed with this software.
+#-----------------------------------------------------------------------------
+
# Standard libary imports.
from base64 import decodestring
import os
@@ -7,6 +15,7 @@
from IPython.external.qt import QtCore, QtGui
# Local imports
+from IPython.utils.traitlets import Bool
from IPython.frontend.qt.svg import save_svg, svg_to_clipboard, svg_to_image
from ipython_widget import IPythonWidget
@@ -19,7 +28,7 @@ class RichIPythonWidget(IPythonWidget):
# RichIPythonWidget protected class variables.
_payload_source_plot = 'IPython.zmq.pylab.backend_payload.add_plot_payload'
-
+ _jpg_supported = Bool(False)
#---------------------------------------------------------------------------
# 'object' interface
#---------------------------------------------------------------------------
@@ -36,6 +45,13 @@ def __init__(self, *args, **kw):
# Dictionary for resolving document resource names to SVG data.
self._name_to_svg_map = {}
+ # Do we support jpg ?
+ # it seems that sometime jpg support is a plugin of QT, so try to assume
+ # it is not always supported.
+ _supported_format = map(str, QtGui.QImageReader.supportedImageFormats())
+ self._jpg_supported = 'jpeg' in _supported_format
+
+
#---------------------------------------------------------------------------
# 'ConsoleWidget' protected interface
#---------------------------------------------------------------------------
@@ -65,6 +81,15 @@ def _context_menu_make(self, pos):
#---------------------------------------------------------------------------
# 'BaseFrontendMixin' abstract interface
#---------------------------------------------------------------------------
+ def _pre_image_append(self, msg, prompt_number):
+ """ Append the Out[] prompt and make the output nicer
+
+ Shared code for some the following if statement
+ """
+ self.log.debug("pyout: %s", msg.get('content', ''))
+ self._append_plain_text(self.output_sep, True)
+ self._append_html(self._make_out_prompt(prompt_number), True)
+ self._append_plain_text('\n', True)
def _handle_pyout(self, msg):
""" Overridden to handle rich data types, like SVG.
@@ -74,19 +99,17 @@ def _handle_pyout(self, msg):
prompt_number = content['execution_count']
data = content['data']
if data.has_key('image/svg+xml'):
- self.log.debug("pyout: %s", msg.get('content', ''))
- self._append_plain_text(self.output_sep, True)
- self._append_html(self._make_out_prompt(prompt_number), True)
+ self._pre_image_append(msg, prompt_number)
self._append_svg(data['image/svg+xml'], True)
self._append_html(self.output_sep2, True)
elif data.has_key('image/png'):
- self.log.debug("pyout: %s", msg.get('content', ''))
- self._append_plain_text(self.output_sep, True)
- self._append_html(self._make_out_prompt(prompt_number), True)
- # This helps the output to look nice.
- self._append_plain_text('\n', True)
+ self._pre_image_append(msg, prompt_number)
self._append_png(decodestring(data['image/png'].encode('ascii')), True)
self._append_html(self.output_sep2, True)
+ elif data.has_key('image/jpeg') and self._jpg_supported:
+ self._pre_image_append(msg, prompt_number)
+ self._append_jpg(decodestring(data['image/jpeg'].encode('ascii')), True)
+ self._append_html(self.output_sep2, True)
else:
# Default back to the plain text representation.
return super(RichIPythonWidget, self)._handle_pyout(msg)
@@ -110,6 +133,10 @@ def _handle_display_data(self, msg):
# in a JSON structure so we decode it.
png = decodestring(data['image/png'].encode('ascii'))
self._append_png(png, True)
+ elif data.has_key('image/jpeg') and self._jpg_supported:
+ self.log.debug("display: %s", msg.get('content', ''))
+ jpg = decodestring(data['image/jpeg'].encode('ascii'))
+ self._append_jpg(jpg, True)
else:
# Default back to the plain text representation.
return super(RichIPythonWidget, self)._handle_display_data(msg)
@@ -118,6 +145,10 @@ def _handle_display_data(self, msg):
# 'RichIPythonWidget' protected interface
#---------------------------------------------------------------------------
+ def _append_jpg(self, jpg, before_prompt=False):
+ """ Append raw JPG data to the widget."""
+ self._append_custom(self._insert_jpg, jpg, before_prompt)
+
def _append_png(self, png, before_prompt=False):
""" Append raw PNG data to the widget.
"""
@@ -168,10 +199,10 @@ def _get_image_tag(self, match, path = None, format = "png"):
written (e.g., for linked images). If None, all images are to be
included inline.
- format : "png"|"svg", optional [default "png"]
+ format : "png"|"svg"|"jpg", optional [default "png"]
Format for returned or referenced images.
"""
- if format == "png":
+ if format in ("png","jpg"):
try:
image = self._get_image(match.group("name"))
except KeyError:
@@ -181,20 +212,20 @@ def _get_image_tag(self, match, path = None, format = "png"):
if not os.path.exists(path):
os.mkdir(path)
relpath = os.path.basename(path)
- if image.save("%s/qt_img%s.png" % (path,match.group("name")),
+ if image.save("%s/qt_img%s.%s" % (path, match.group("name"), format),
"PNG"):
- return '<img src="%s/qt_img%s.png">' % (relpath,
- match.group("name"))
+ return '<img src="%s/qt_img%s.%s">' % (relpath,
+ match.group("name"),format)
else:
return "<b>Couldn't save image!</b>"
else:
ba = QtCore.QByteArray()
buffer_ = QtCore.QBuffer(ba)
buffer_.open(QtCore.QIODevice.WriteOnly)
- image.save(buffer_, "PNG")
+ image.save(buffer_, format.upper())
buffer_.close()
- return '<img src="data:image/png;base64,\n%s\n" />' % (
- re.sub(r'(.{60})',r'\1\n',str(ba.toBase64())))
+ return '<img src="data:image/%s;base64,\n%s\n" />' % (
+ format,re.sub(r'(.{60})',r'\1\n',str(ba.toBase64())))
elif format == "svg":
try:
@@ -215,14 +246,22 @@ def _get_image_tag(self, match, path = None, format = "png"):
else:
return '<b>Unrecognized image format</b>'
+ def _insert_jpg(self, cursor, jpg):
+ """ Insert raw PNG data into the widget."""
+ self._insert_img(cursor, jpg, 'jpg')
+
def _insert_png(self, cursor, png):
""" Insert raw PNG data into the widget.
"""
+ self._insert_img(cursor, png, 'png')
+
+ def _insert_img(self, cursor, img, fmt):
+ """ insert a raw image, jpg or png """
try:
image = QtGui.QImage()
- image.loadFromData(png, 'PNG')
+ image.loadFromData(img, fmt.upper())
except ValueError:
- self._insert_plain_text(cursor, 'Received invalid PNG data.')
+ self._insert_plain_text(cursor, 'Received invalid %s data.'%fmt)
else:
format = self._add_image(image)
cursor.insertBlock()
Something went wrong with that request. Please try again.