##// END OF EJS Templates
handle jpg/jpeg in the qtconsole....
Matthias BUSSONNIER -
Show More
@@ -1,3 +1,11
1 #-----------------------------------------------------------------------------
2 # Copyright (c) 2010-2012, IPython Development Team.
3 #
4 # Distributed under the terms of the Modified BSD License.
5 #
6 # The full license is in the file COPYING.txt, distributed with this software.
7 #-----------------------------------------------------------------------------
8
1 9 # Standard libary imports.
2 10 from base64 import decodestring
3 11 import os
@@ -36,6 +44,12 class RichIPythonWidget(IPythonWidget):
36 44 # Dictionary for resolving document resource names to SVG data.
37 45 self._name_to_svg_map = {}
38 46
47 # Do we support jpg ?
48 # it seems that sometime jpg support is a plugin of QT, so try to assume
49 # it is not always supported.
50 self._supported_format = map(str,QtGui.QImageReader.supportedImageFormats())
51 self._jpg_supported = 'jpeg' in self._supported_format
52
39 53 #---------------------------------------------------------------------------
40 54 # 'ConsoleWidget' protected interface
41 55 #---------------------------------------------------------------------------
@@ -69,24 +83,35 class RichIPythonWidget(IPythonWidget):
69 83 def _handle_pyout(self, msg):
70 84 """ Overridden to handle rich data types, like SVG.
71 85 """
86 def pre_image_append():
87 self.log.debug("pyout: %s", msg.get('content', ''))
88 self._append_plain_text(self.output_sep, True)
89 self._append_html(self._make_out_prompt(prompt_number), True)
90 # This helps the output to look nice.
91 self._append_plain_text('\n', True)
92
72 93 if not self._hidden and self._is_from_this_session(msg):
73 94 content = msg['content']
74 95 prompt_number = content['execution_count']
75 96 data = content['data']
76 97 if data.has_key('image/svg+xml'):
77 self.log.debug("pyout: %s", msg.get('content', ''))
78 self._append_plain_text(self.output_sep, True)
79 self._append_html(self._make_out_prompt(prompt_number), True)
98 pre_image_append()
80 99 self._append_svg(data['image/svg+xml'], True)
81 100 self._append_html(self.output_sep2, True)
82 101 elif data.has_key('image/png'):
83 self.log.debug("pyout: %s", msg.get('content', ''))
84 self._append_plain_text(self.output_sep, True)
85 self._append_html(self._make_out_prompt(prompt_number), True)
86 # This helps the output to look nice.
87 self._append_plain_text('\n', True)
102 pre_image_append()
88 103 self._append_png(decodestring(data['image/png'].encode('ascii')), True)
89 104 self._append_html(self.output_sep2, True)
105 elif data.has_key('image/jpeg') and self._jpg_supported:
106 pre_image_append()
107 self._append_jpg(decodestring(data['image/jpeg'].encode('ascii')), True)
108 self._append_html(self.output_sep2, True)
109 # image/jpg should be an invalid mimetype, but python mimetype package
110 # handel it.
111 elif data.has_key('image/jpg') and self._jpg_supported:
112 pre_image_append()
113 self._append_jpg(decodestring(data['image/jpg'].encode('ascii')), True)
114 self._append_html(self.output_sep2, True)
90 115 else:
91 116 # Default back to the plain text representation.
92 117 return super(RichIPythonWidget, self)._handle_pyout(msg)
@@ -110,6 +135,14 class RichIPythonWidget(IPythonWidget):
110 135 # in a JSON structure so we decode it.
111 136 png = decodestring(data['image/png'].encode('ascii'))
112 137 self._append_png(png, True)
138 elif data.has_key('image/jpeg') and self._jpg_supported:
139 self.log.debug("display: %s", msg.get('content', ''))
140 jpg = decodestring(data['image/jpeg'].encode('ascii'))
141 self._append_jpg(jpg, True)
142 elif data.has_key('image/jpg') and self._jpg_supported:
143 self.log.debug("display: %s", msg.get('content', ''))
144 jpg = decodestring(data['image/jpg'].encode('ascii'))
145 self._append_jpg(jpg, True)
113 146 else:
114 147 # Default back to the plain text representation.
115 148 return super(RichIPythonWidget, self)._handle_display_data(msg)
@@ -118,6 +151,10 class RichIPythonWidget(IPythonWidget):
118 151 # 'RichIPythonWidget' protected interface
119 152 #---------------------------------------------------------------------------
120 153
154 def _append_jpg(self, jpg, before_prompt=False):
155 """ Append raw JPG data to the widget."""
156 self._append_custom(self._insert_jpg, jpg, before_prompt)
157
121 158 def _append_png(self, png, before_prompt=False):
122 159 """ Append raw PNG data to the widget.
123 160 """
@@ -168,10 +205,10 class RichIPythonWidget(IPythonWidget):
168 205 written (e.g., for linked images). If None, all images are to be
169 206 included inline.
170 207
171 format : "png"|"svg", optional [default "png"]
208 format : "png"|"svg"|"jpg", optional [default "png"]
172 209 Format for returned or referenced images.
173 210 """
174 if format == "png":
211 if format in ("png","jpg"):
175 212 try:
176 213 image = self._get_image(match.group("name"))
177 214 except KeyError:
@@ -181,20 +218,20 class RichIPythonWidget(IPythonWidget):
181 218 if not os.path.exists(path):
182 219 os.mkdir(path)
183 220 relpath = os.path.basename(path)
184 if image.save("%s/qt_img%s.png" % (path,match.group("name")),
221 if image.save("%s/qt_img%s.%s" % (path,match.group("name"),format),
185 222 "PNG"):
186 return '<img src="%s/qt_img%s.png">' % (relpath,
187 match.group("name"))
223 return '<img src="%s/qt_img%s.%s">' % (relpath,
224 match.group("name"),format)
188 225 else:
189 226 return "<b>Couldn't save image!</b>"
190 227 else:
191 228 ba = QtCore.QByteArray()
192 229 buffer_ = QtCore.QBuffer(ba)
193 230 buffer_.open(QtCore.QIODevice.WriteOnly)
194 image.save(buffer_, "PNG")
231 image.save(buffer_, format.upper())
195 232 buffer_.close()
196 return '<img src="data:image/png;base64,\n%s\n" />' % (
197 re.sub(r'(.{60})',r'\1\n',str(ba.toBase64())))
233 return '<img src="data:image/%s;base64,\n%s\n" />' % (
234 format,re.sub(r'(.{60})',r'\1\n',str(ba.toBase64())))
198 235
199 236 elif format == "svg":
200 237 try:
@@ -215,14 +252,22 class RichIPythonWidget(IPythonWidget):
215 252 else:
216 253 return '<b>Unrecognized image format</b>'
217 254
255 def _insert_jpg(self, cursor, jpg):
256 """ Insert raw PNG data into the widget."""
257 self._insert_img(cursor, jpg, 'jpg')
258
218 259 def _insert_png(self, cursor, png):
219 260 """ Insert raw PNG data into the widget.
220 261 """
262 self._insert_img(cursor, png, 'png')
263
264 def _insert_img(self, cursor, img, fmt):
265 """ insert a raw image, jpg or png """
221 266 try:
222 267 image = QtGui.QImage()
223 image.loadFromData(png, 'PNG')
268 image.loadFromData(img, fmt.upper())
224 269 except ValueError:
225 self._insert_plain_text(cursor, 'Received invalid PNG data.')
270 self._insert_plain_text(cursor, 'Received invalid %s data.'%fmt)
226 271 else:
227 272 format = self._add_image(image)
228 273 cursor.insertBlock()
General Comments 0
You need to be logged in to leave comments. Login now