##// END OF EJS Templates
handle jpg/jpeg in the qtconsole....
Matthias BUSSONNIER -
Show More
@@ -1,3 +1,11 b''
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 # Standard libary imports.
9 # Standard libary imports.
2 from base64 import decodestring
10 from base64 import decodestring
3 import os
11 import os
@@ -36,6 +44,12 b' class RichIPythonWidget(IPythonWidget):'
36 # Dictionary for resolving document resource names to SVG data.
44 # Dictionary for resolving document resource names to SVG data.
37 self._name_to_svg_map = {}
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 # 'ConsoleWidget' protected interface
54 # 'ConsoleWidget' protected interface
41 #---------------------------------------------------------------------------
55 #---------------------------------------------------------------------------
@@ -69,24 +83,35 b' class RichIPythonWidget(IPythonWidget):'
69 def _handle_pyout(self, msg):
83 def _handle_pyout(self, msg):
70 """ Overridden to handle rich data types, like SVG.
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 if not self._hidden and self._is_from_this_session(msg):
93 if not self._hidden and self._is_from_this_session(msg):
73 content = msg['content']
94 content = msg['content']
74 prompt_number = content['execution_count']
95 prompt_number = content['execution_count']
75 data = content['data']
96 data = content['data']
76 if data.has_key('image/svg+xml'):
97 if data.has_key('image/svg+xml'):
77 self.log.debug("pyout: %s", msg.get('content', ''))
98 pre_image_append()
78 self._append_plain_text(self.output_sep, True)
79 self._append_html(self._make_out_prompt(prompt_number), True)
80 self._append_svg(data['image/svg+xml'], True)
99 self._append_svg(data['image/svg+xml'], True)
81 self._append_html(self.output_sep2, True)
100 self._append_html(self.output_sep2, True)
82 elif data.has_key('image/png'):
101 elif data.has_key('image/png'):
83 self.log.debug("pyout: %s", msg.get('content', ''))
102 pre_image_append()
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)
88 self._append_png(decodestring(data['image/png'].encode('ascii')), True)
103 self._append_png(decodestring(data['image/png'].encode('ascii')), True)
89 self._append_html(self.output_sep2, True)
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 else:
115 else:
91 # Default back to the plain text representation.
116 # Default back to the plain text representation.
92 return super(RichIPythonWidget, self)._handle_pyout(msg)
117 return super(RichIPythonWidget, self)._handle_pyout(msg)
@@ -110,6 +135,14 b' class RichIPythonWidget(IPythonWidget):'
110 # in a JSON structure so we decode it.
135 # in a JSON structure so we decode it.
111 png = decodestring(data['image/png'].encode('ascii'))
136 png = decodestring(data['image/png'].encode('ascii'))
112 self._append_png(png, True)
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 else:
146 else:
114 # Default back to the plain text representation.
147 # Default back to the plain text representation.
115 return super(RichIPythonWidget, self)._handle_display_data(msg)
148 return super(RichIPythonWidget, self)._handle_display_data(msg)
@@ -118,6 +151,10 b' class RichIPythonWidget(IPythonWidget):'
118 # 'RichIPythonWidget' protected interface
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 def _append_png(self, png, before_prompt=False):
158 def _append_png(self, png, before_prompt=False):
122 """ Append raw PNG data to the widget.
159 """ Append raw PNG data to the widget.
123 """
160 """
@@ -168,10 +205,10 b' class RichIPythonWidget(IPythonWidget):'
168 written (e.g., for linked images). If None, all images are to be
205 written (e.g., for linked images). If None, all images are to be
169 included inline.
206 included inline.
170
207
171 format : "png"|"svg", optional [default "png"]
208 format : "png"|"svg"|"jpg", optional [default "png"]
172 Format for returned or referenced images.
209 Format for returned or referenced images.
173 """
210 """
174 if format == "png":
211 if format in ("png","jpg"):
175 try:
212 try:
176 image = self._get_image(match.group("name"))
213 image = self._get_image(match.group("name"))
177 except KeyError:
214 except KeyError:
@@ -181,20 +218,20 b' class RichIPythonWidget(IPythonWidget):'
181 if not os.path.exists(path):
218 if not os.path.exists(path):
182 os.mkdir(path)
219 os.mkdir(path)
183 relpath = os.path.basename(path)
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 "PNG"):
222 "PNG"):
186 return '<img src="%s/qt_img%s.png">' % (relpath,
223 return '<img src="%s/qt_img%s.%s">' % (relpath,
187 match.group("name"))
224 match.group("name"),format)
188 else:
225 else:
189 return "<b>Couldn't save image!</b>"
226 return "<b>Couldn't save image!</b>"
190 else:
227 else:
191 ba = QtCore.QByteArray()
228 ba = QtCore.QByteArray()
192 buffer_ = QtCore.QBuffer(ba)
229 buffer_ = QtCore.QBuffer(ba)
193 buffer_.open(QtCore.QIODevice.WriteOnly)
230 buffer_.open(QtCore.QIODevice.WriteOnly)
194 image.save(buffer_, "PNG")
231 image.save(buffer_, format.upper())
195 buffer_.close()
232 buffer_.close()
196 return '<img src="data:image/png;base64,\n%s\n" />' % (
233 return '<img src="data:image/%s;base64,\n%s\n" />' % (
197 re.sub(r'(.{60})',r'\1\n',str(ba.toBase64())))
234 format,re.sub(r'(.{60})',r'\1\n',str(ba.toBase64())))
198
235
199 elif format == "svg":
236 elif format == "svg":
200 try:
237 try:
@@ -215,14 +252,22 b' class RichIPythonWidget(IPythonWidget):'
215 else:
252 else:
216 return '<b>Unrecognized image format</b>'
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 def _insert_png(self, cursor, png):
259 def _insert_png(self, cursor, png):
219 """ Insert raw PNG data into the widget.
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 try:
266 try:
222 image = QtGui.QImage()
267 image = QtGui.QImage()
223 image.loadFromData(png, 'PNG')
268 image.loadFromData(img, fmt.upper())
224 except ValueError:
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 else:
271 else:
227 format = self._add_image(image)
272 format = self._add_image(image)
228 cursor.insertBlock()
273 cursor.insertBlock()
General Comments 0
You need to be logged in to leave comments. Login now