Skip to content


Subversion checkout URL

You can clone with
Download ZIP


Inconsistency embedding remote png, jpg and gif files #2115

ghost opened this Issue · 10 comments

5 participants


In the Notebook, if you import Image from IPython.display and pass a URL when you call it, the image displays if it is a png or jpg, but not if it's a gif. If you pass the URL as a named argument, it works fine for all three image types.

from IPython.display import Image
Image('') # this works for png and jpg files

UnicodeDecodeError                        Traceback (most recent call last)
<ipython-input-51-7700501916dc> in <module>()
----> 1 Image('')

/usr/local/lib/python2.7/dist-packages/IPython/core/displayhook.pyc in __call__(self, result)
    240             self.update_user_ns(result)
    241             self.log_output(format_dict)
--> 242             self.finish_displayhook()
    244     def flush(self):

/usr/local/lib/python2.7/dist-packages/IPython/zmq/displayhook.pyc in finish_displayhook(self)
     59         sys.stdout.flush()
     60         sys.stderr.flush()
---> 61         self.session.send(self.pub_socket, self.msg, ident=self.topic)
     62         self.msg = None

/usr/local/lib/python2.7/dist-packages/IPython/zmq/session.pyc in send(self, stream, msg_or_type, content, parent, ident, buffers, subheader, track, header)
    558         buffers = [] if buffers is None else buffers
--> 559         to_send = self.serialize(msg, ident)
    560         flag = 0
    561         if buffers:

/usr/local/lib/python2.7/dist-packages/IPython/zmq/session.pyc in serialize(self, msg, ident)
    461             content = self.none
    462         elif isinstance(content, dict):
--> 463             content = self.pack(content)
    464         elif isinstance(content, bytes):
    465             # content is already packed, as in a relayed message

/usr/local/lib/python2.7/dist-packages/IPython/zmq/session.pyc in <lambda>(obj)
     77 # ISO8601-ify datetime objects
---> 78 json_packer = lambda obj: jsonapi.dumps(obj, default=date_default)
     79 json_unpacker = lambda s: extract_dates(jsonapi.loads(s))

/usr/lib/python2.7/dist-packages/zmq/utils/jsonapi.pyc in dumps(o, **kwargs)
     72     """%jsonmod
---> 74     return _squash_unicode(jsonmod.dumps(o, separators=(',',':'),**kwargs))
     76 def loads(s,**kwargs):

/usr/lib/python2.7/dist-packages/simplejson/__init__.pyc in dumps(obj, skipkeys, ensure_ascii, check_circular, allow_nan, cls, indent, separators, encoding, default, use_decimal, namedtuple_as_object, tuple_as_array, **kw)
    294         namedtuple_as_object=namedtuple_as_object,
    295         tuple_as_array=tuple_as_array,
--> 296         **kw).encode(obj)

/usr/lib/python2.7/dist-packages/simplejson/encoder.pyc in encode(self, o)
    224         # exceptions aren't as detailed.  The list call should be roughly
    225         # equivalent to the PySequence_Fast that ''.join() would do.
--> 226         chunks = self.iterencode(o, _one_shot=True)
    227         if not isinstance(chunks, (list, tuple)):
    228             chunks = list(chunks)

/usr/lib/python2.7/dist-packages/simplejson/encoder.pyc in iterencode(self, o, _one_shot)
    294                 self.namedtuple_as_object, self.tuple_as_array)
    295         try:
--> 296             return _iterencode(o, 0)
    297         finally:
    298             key_memo.clear()

UnicodeDecodeError: 'utf8' codec can't decode byte 0xd3 in position 6: invalid continuation byte

just FYI,


Need to guess he format of the image, decode it, make it into PNG, and base64 encode it to send to the browser.
So each image type have to have its own branch in the code

Wherease if you pass the url as a named argument, this 'just' publish an <img> tag, with the source pointing to the URL, so this uses the display capability of the browser. (see 00_notebook-tour for more explanation)

Then, I think you would get the same behavior with all kind of image type depending on the which one a browser support.
Gifs are of course really common, but I guess with the current mechanism, we might loose gifs with animations.


I think it will end in fixing the example. See mailing list.


Do we plan to support embedding GIFs? If not, then this is really a docs issue, indicating that GIFs must be passed by URL, rather than embedded.

@minrk minrk referenced this issue from a commit
Commit has since been removed from the repository and is no longer available.
@minrk minrk referenced this issue from a commit
@minrk minrk Backport PR #2117: use explicit url in notebook example
related to #2115

Either we support gifs, or we don't embed them in notebook example.

Should be backported on 0.13.1

So, currently, is there a method to display a local gif file?


Image(url="localfile.gif") will work. It's just embedding that doesn't.


sweet. i should have tried that. thanks

@minrk minrk removed the prio-medium label

I just tripped over this trying to display Sage animations in the IPython notebook. Is there any plan for animations beyond working around the lack of options in javascript?

Also, why do you embed user output in json? IMHO everything that is computed should be base64-encoded in json. And IMHO not just image data, even if you think it should be valid utf8 (say, html) the user may or may not have gotten the encoding right. Under pretty much no circumstance is a lengthy UnicodeDecodeError from deep inside the zmq kernel the desired output.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.