diff --git a/src/safeds/data/image/containers/_image.py b/src/safeds/data/image/containers/_image.py index 39f26f194..3e0269c76 100644 --- a/src/safeds/data/image/containers/_image.py +++ b/src/safeds/data/image/containers/_image.py @@ -6,6 +6,7 @@ from typing import Any, BinaryIO import PIL +from PIL import ImageFilter from PIL.Image import Image as PillowImage from PIL.Image import open as open_image @@ -274,3 +275,30 @@ def flip_horizontally(self) -> Image: imagecopy = copy.deepcopy(self) imagecopy._image = self._image.transpose(PIL.Image.FLIP_LEFT_RIGHT) return imagecopy + + def blur(self, radius: int = 1) -> Image: + """ + Return the blurred image. + + Parameters + ---------- + radius : int + Radius is directly proportional to the blur value. The radius is equal to the amount of pixels united in each direction. + A Radius of 1 will result in a united box of 9 pixels. + + Returns + ------- + result : Image + The blurred image + """ + 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 = new_image._image.filter(ImageFilter.BoxBlur(radius)) + return new_image diff --git a/tests/resources/image/blurredboy.jpg b/tests/resources/image/blurredboy.jpg new file mode 100644 index 000000000..f546896b2 Binary files /dev/null and b/tests/resources/image/blurredboy.jpg differ diff --git a/tests/resources/image/blurredboy.png b/tests/resources/image/blurredboy.png new file mode 100644 index 000000000..4b3d77676 Binary files /dev/null and b/tests/resources/image/blurredboy.png differ diff --git a/tests/resources/image/boy.jpg b/tests/resources/image/boy.jpg new file mode 100644 index 000000000..6f383ba74 Binary files /dev/null and b/tests/resources/image/boy.jpg differ diff --git a/tests/resources/image/boy.png b/tests/resources/image/boy.png new file mode 100644 index 000000000..20360eeff Binary files /dev/null and b/tests/resources/image/boy.png differ diff --git a/tests/safeds/data/image/containers/test_image.py b/tests/safeds/data/image/containers/test_image.py index 781e48672..f74603fe2 100644 --- a/tests/safeds/data/image/containers/test_image.py +++ b/tests/safeds/data/image/containers/test_image.py @@ -249,6 +249,26 @@ def test_should_be_original(self) -> None: assert image == image2 +class TestBlur: + def test_should_return_blurred_png_image(self) -> None: + image = Image.from_png_file(resolve_resource_path("image/boy.png")) + image = image.blur(2) + image.to_png_file(resolve_resource_path("image/blurredboy1.png")) + image = Image.from_png_file(resolve_resource_path("image/blurredboy1.png")) + image2 = Image.from_png_file(resolve_resource_path("image/blurredboy.png")) + assert image._image == image2._image + + def test_should_return_blurred_jpg_image(self) -> None: + image = Image.from_jpeg_file(resolve_resource_path("image/boy.jpg")) + image = image.blur(2) + image.to_jpeg_file(resolve_resource_path("image/blurredboy1.jpg")) + image = Image.from_jpeg_file(resolve_resource_path("image/blurredboy1.jpg")) + image2 = Image.from_jpeg_file(resolve_resource_path("image/blurredboy.jpg")) + assert image._image == image2._image + Path.unlink(Path(resolve_resource_path("image/blurredboy1.jpg"))) + Path.unlink(Path(resolve_resource_path("image/blurredboy1.png"))) + + class TestCrop: def test_should_crop_jpg_image(self) -> None: image = Image.from_jpeg_file(resolve_resource_path("image/white.jpg"))