From 1e4d110da9516fd1f95f2e9d7737ebeef250eb6a Mon Sep 17 00:00:00 2001 From: Simon Breuer <86068340+sibre28@users.noreply.github.com> Date: Fri, 16 Jun 2023 15:52:00 +0200 Subject: [PATCH] feat: added invert_colors method (#367) Closes #[282]. ### Summary of Changes added `invert_colors` method to `Image` added tests Co-authored-by: PhilipGutberlet <92990487+PhilipGutberlet@users.noreply.github.com> --------- Co-authored-by: PhilipGutberlet <92990487+PhilipGutberlet@users.noreply.github.com> Co-authored-by: megalinter-bot <129584137+megalinter-bot@users.noreply.github.com> --- src/safeds/data/image/containers/_image.py | 23 +++++++++++++++++- .../image/inverted_colors_original.jpg | Bin 0 -> 25944 bytes .../image/inverted_colors_original.png | Bin 0 -> 6751 bytes tests/resources/image/original.jpg | Bin 0 -> 8728 bytes .../data/image/containers/test_image.py | 17 +++++++++++++ 5 files changed, 39 insertions(+), 1 deletion(-) create mode 100644 tests/resources/image/inverted_colors_original.jpg create mode 100644 tests/resources/image/inverted_colors_original.png create mode 100644 tests/resources/image/original.jpg diff --git a/src/safeds/data/image/containers/_image.py b/src/safeds/data/image/containers/_image.py index 41309159e..c5f9c2b31 100644 --- a/src/safeds/data/image/containers/_image.py +++ b/src/safeds/data/image/containers/_image.py @@ -6,7 +6,7 @@ from typing import Any, BinaryIO import PIL -from PIL import ImageFilter +from PIL import ImageFilter, ImageOps from PIL.Image import Image as PillowImage from PIL.Image import open as open_image @@ -316,3 +316,24 @@ def blur(self, radius: int = 1) -> Image: new_image = Image(data, self._format) new_image._image = new_image._image.filter(ImageFilter.BoxBlur(radius)) return new_image + + def invert_colors(self) -> Image: + """ + Return the image with inverted colors. + + Returns + ------- + result : Image + The image with inverted colors. + """ + data = io.BytesIO() + repr_png = self._repr_png_() + repr_jpeg = self._repr_jpeg_() + if repr_png is not None: + data = io.BytesIO(repr_png) + elif repr_jpeg is not None: + data = io.BytesIO(repr_jpeg) + + new_image = Image(data, self._format) + new_image._image = ImageOps.invert(new_image._image) + return new_image diff --git a/tests/resources/image/inverted_colors_original.jpg b/tests/resources/image/inverted_colors_original.jpg new file mode 100644 index 0000000000000000000000000000000000000000..7d23aea989e71fc90f906779b3646a213eb6d4b0 GIT binary patch literal 25944 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 Kh8)mePW~6SC(+OV literal 0 HcmV?d00001 diff --git a/tests/safeds/data/image/containers/test_image.py b/tests/safeds/data/image/containers/test_image.py index 199892fc7..19ca708f1 100644 --- a/tests/safeds/data/image/containers/test_image.py +++ b/tests/safeds/data/image/containers/test_image.py @@ -265,6 +265,23 @@ def test_should_be_original(self) -> None: assert image == image2 +class TestInvertColors: + def test_should_invert_colors_png(self) -> None: + image = Image.from_png_file(resolve_resource_path("image/original.png")) + image = image.invert_colors() + image2 = Image.from_png_file(resolve_resource_path("image/inverted_colors_original.png")) + assert image == image2 + + def test_should_invert_colors_jpeg(self) -> None: + image = Image.from_jpeg_file(resolve_resource_path("image/original.jpg")) + image = image.invert_colors() + image.to_jpeg_file(resolve_resource_path("image/inverted_colors_original1.jpg")) + image = Image.from_jpeg_file(resolve_resource_path("image/inverted_colors_original1.jpg")) + image2 = Image.from_jpeg_file(resolve_resource_path("image/inverted_colors_original.jpg")) + assert image == image2 + Path.unlink(Path(resolve_resource_path("image/inverted_colors_original1.jpg"))) + + class TestBlur: def test_should_return_blurred_png_image(self) -> None: image = Image.from_png_file(resolve_resource_path("image/boy.png"))