diff --git a/Tests/test_file_jpeg.py b/Tests/test_file_jpeg.py index 73a00386f6f..0247527f5b2 100644 --- a/Tests/test_file_jpeg.py +++ b/Tests/test_file_jpeg.py @@ -922,6 +922,19 @@ def closure(mode, *args): im.load() ImageFile.LOAD_TRUNCATED_IMAGES = False + def test_repr_jpeg(self): + im = hopper() + + with Image.open(BytesIO(im._repr_jpeg_())) as repr_jpeg: + assert repr_jpeg.format == "JPEG" + assert_image_similar(im, repr_jpeg, 17) + + def test_repr_jpeg_error(self): + im = hopper("F") + + with pytest.raises(ValueError): + im._repr_jpeg_() + @pytest.mark.skipif(not is_win32(), reason="Windows only") @skip_unless_feature("jpg") diff --git a/docs/releasenotes/10.0.0.rst b/docs/releasenotes/10.0.0.rst index e2005b710e6..ececfa20d74 100644 --- a/docs/releasenotes/10.0.0.rst +++ b/docs/releasenotes/10.0.0.rst @@ -160,6 +160,18 @@ TODO Other Changes ============= +Support display_jpeg() in IPython +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +In addition to ``display()`` and ``display_png``, ``display_jpeg()`` can now +also be used to display images in IPython:: + + from PIL import Image + from IPython.display import display_jpeg + + im = Image.new("RGB", (100, 100), (255, 0, 0)) + display_jpeg(im) + Support reading signed 8-bit TIFF images ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/src/PIL/Image.py b/src/PIL/Image.py index bee9e23d088..e0fb6a8858c 100644 --- a/src/PIL/Image.py +++ b/src/PIL/Image.py @@ -633,19 +633,34 @@ def _repr_pretty_(self, p, cycle): ) ) - def _repr_png_(self): - """iPython display hook support + def _repr_image(self, image_format): + """Helper function for iPython display hook. - :returns: png version of the image as bytes + :param image_format: Image format. + :returns: image as bytes, saved into the given format. """ b = io.BytesIO() try: - self.save(b, "PNG") + self.save(b, image_format) except Exception as e: - msg = "Could not save to PNG for display" + msg = f"Could not save to {image_format} for display" raise ValueError(msg) from e return b.getvalue() + def _repr_png_(self): + """iPython display hook support for PNG format. + + :returns: PNG version of the image as bytes + """ + return self._repr_image("PNG") + + def _repr_jpeg_(self): + """iPython display hook support for JPEG format. + + :returns: JPEG version of the image as bytes + """ + return self._repr_image("JPEG") + @property def __array_interface__(self): # numpy array interface support @@ -1108,7 +1123,6 @@ def quantize( Available methods are :data:`Dither.NONE` or :data:`Dither.FLOYDSTEINBERG` (default). :returns: A new image - """ self.load()