Handle exceptions in _repr_jpeg_ and _repr_png_

In 10.0.0 a _repr_jpeg_ implementation was added to the Image object to
enable the use of display_jpeg() in IPython environments. However, in
some cases the implementation of this method could result in an
exception being raised while trying to generate the jpeg data. The best
example is if the image data is in an RGBA format as a result of the
object being created by opening a PNG file. In this case trying to save
the Image object as a jpeg will error because the jpeg format can't
represent the transparency in the alpha channel. This results in an
exception being raised in the IPython/Jupyter context when outputing the
image object. However, in cases like this IPython allows the repr
methods to return None to indicate there is no representation in that
format available. [1] This commit updates the _repr_png_ and _repr_jpeg_
methods to catch any exception that might be raised while trying to
generate the image data. If an exception is raised we treat that as not
being able to generate image data in that format and return None
instead.

Related to #7259

[1] https://ipython.readthedocs.io/en/stable/config/integrating.html#custom-methods
This commit is contained in:
Matthew Treinish 2023-07-06 08:42:37 -04:00
parent f089c2db8c
commit 6d440ac995
No known key found for this signature in database
GPG Key ID: FD12A0F214C9E177

View File

@ -651,14 +651,20 @@ class Image:
:returns: PNG version of the image as bytes :returns: PNG version of the image as bytes
""" """
try:
return self._repr_image("PNG", compress_level=1) return self._repr_image("PNG", compress_level=1)
except Exception:
return None
def _repr_jpeg_(self): def _repr_jpeg_(self):
"""iPython display hook support for JPEG format. """iPython display hook support for JPEG format.
:returns: JPEG version of the image as bytes :returns: JPEG version of the image as bytes
""" """
return self._repr_image("JPEG") try:
self._repr_image("JPEG")
except Exception:
return None
@property @property
def __array_interface__(self): def __array_interface__(self):