From eba8163d649d1e4dcdda2ff4fc3e2229249d8940 Mon Sep 17 00:00:00 2001 From: Simon Breuer <86068340+sibre28@users.noreply.github.com> Date: Fri, 16 Jun 2023 15:17:42 +0200 Subject: [PATCH] feat: added crop() method in image and tests (#365) Closes #[284]. ### Summary of Changes Added `crop()` method in `Image` Added tests Co-authored-by: PhilipGutberlet <92990487+PhilipGutberlet@users.noreply.github.com> --------- Co-authored-by: megalinter-bot <129584137+megalinter-bot@users.noreply.github.com> Co-authored-by: Philip Gutberlet <92990487+PhilipGutberlet@users.noreply.github.com> --- src/safeds/data/image/containers/_image.py | 28 ++++++++++++++++++ tests/resources/image/white.jpg | Bin 0 -> 4506 bytes tests/resources/image/white.png | Bin 0 -> 765 bytes tests/resources/image/whiteCropped.jpg | Bin 0 -> 1049 bytes tests/resources/image/whiteCropped.png | Bin 0 -> 131 bytes tests/resources/white.jpg/white.png | Bin 0 -> 765 bytes .../data/image/containers/test_image.py | 14 +++++++++ 7 files changed, 42 insertions(+) create mode 100644 tests/resources/image/white.jpg create mode 100644 tests/resources/image/white.png create mode 100644 tests/resources/image/whiteCropped.jpg create mode 100644 tests/resources/image/whiteCropped.png create mode 100644 tests/resources/white.jpg/white.png diff --git a/src/safeds/data/image/containers/_image.py b/src/safeds/data/image/containers/_image.py index 2c3659859..39f26f194 100644 --- a/src/safeds/data/image/containers/_image.py +++ b/src/safeds/data/image/containers/_image.py @@ -221,6 +221,34 @@ def resize(self, new_width: int, new_height: int) -> Image: new_image._image = new_image._image.resize((new_width, new_height)) return new_image + def crop(self, x: int, y: int, width: int, height: int) -> Image: + """ + Return an image that has been cropped to a given bounding rectangle. + + Parameters + ---------- + x: the x coordinate of the top-left corner of the bounding rectangle + y: the y coordinate of the top-left corner of the bounding rectangle + width: the width of the bounding rectangle + height: the height of the bounding rectangle + + Returns + ------- + result : Image + The image with the + """ + 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.crop((x, y, (x + width), (y + height))) + return new_image + def flip_vertically(self) -> Image: """ Flip the image vertically (horizontal axis, flips up-down and vice versa). diff --git a/tests/resources/image/white.jpg b/tests/resources/image/white.jpg new file mode 100644 index 0000000000000000000000000000000000000000..b15a32d0503eca53c9ba6113bd8240d52c579775 GIT binary patch literal 4506 zcmex=Hq-)3-T;9z58XJh4H zXJ_Z+>Qk2+&~3e1sIqZnVFebm|0m_Sb(Z)f$|J2f~-P{hK_8)fr;!& zg(60c6BlwQJ8e8D8g%i4ig8j=6DOCLxP+vXs+zinrk07RnYo3fm9vYho4bdnS8zyZ zSa?KaRB}pcT6#uiR&hybS$RceRdY*gTYE=m*QCi)rcRqaW9F9X@jO*zpr5PhGlvugFVB~e_h%y|1;b? z{?GH-!v743k@jCgLKr`@ihlnq!uVk@Q{VnG^!;aeGOuF#zk}iNzcg1r;$pz?O6X_S zTKnG?{~1o&T(N(nt^Tj8tHHLZOJe~OjWA#R@%m5xHs1dk5>~JOD{}QCYwiBW`+us> zQ~l4dA@uscuB;zT4P3wKzZL#xm{hr<{zjPpUs2JTgYo|V&e?zRH|77$b@D&MqD2e% z6Bc!8Fwh7y&;NM;&*bw${~2y*z5dVOYFgtMpa0|iKhNi#^>0K=fex6pPhkPmzWIOW z)IXV*CI3xyGEkLkyg~To{|uY^|4csX{O{1F`WGu!FyGKv)Wtw6{QOV(e+HG$NA`c? z+V!8|qHnxF`0anzppbhM|C=?o{>8HO9U2Vlm;Yx-m;b3gtNm|l3Q$>K_!-eJ{~6vq z2I&m|hWncNzqGU%zHwRi{Ldf@N@XAQ|2D1L|0Ov5i0EhnB|ia=CQxc8)X@Y= z)zWk{fsQ87(JGz_RsU!ePxZDaac$7A{O$4*_7CHKR6X|mcj$Nh+_LL-`M3V8Nfj)6 zoLpaQdA{n?FAe7V{}~=G+y5%?Kf|f%{~59t|C7r8w^aVm%KC4sK5&gnj|R(7Ne*{R v@86RDoqzb&JYZLbWBcT9uRU}3+<(h^+k9c{jZeo4=R8*0W7nm@{Qo8ZTM5O2 literal 0 HcmV?d00001 diff --git a/tests/resources/image/white.png b/tests/resources/image/white.png new file mode 100644 index 0000000000000000000000000000000000000000..4849863e890063b6d48b1d2c8691eebde0cbdc63 GIT binary patch literal 765 zcmeAS@N?(olHy`uVBq!ia0y~yV4MKNIvhX&h7)&o$pIT$Gwvl3(N)w?_jgDGZWyEG@~%F9OSk%AKpD#B6 zO6yjIM3lIs7AF^F7L;V>=P@vF%sj23sk!0Ob$xyP>)IZkmvv8`Kd*Vs``md}hP?S4 zAE&R^*}=fTWaa7N7*cWT?KN*dCr62vi@TJjx2v4H^Pf*v!f}eXWdVorWHYtr(N1&! zP4-jqoTT!yf7Yg7S?j$`w`K4CV#LU(q~O59($T;mD4^ibz`-E^72yz2U}AECiZDSH zfJGR{(Za+6HyLObBiv-5?O>~6b|D^(PF6}rMnOeST|r4lSw=>~TvNxu(8R<c1}I=;VrF4wW9Q)H;sz?% zD!{d!pzFb!U9xX3zTPI5o8roG<0MW4oqZMDikqloVbuf*=gfJ(V&YTRE(2~ znmD<{#3dx9RMpfqG__1j&CD$#!_R+R+Asez+&uly^WDP#42hBUUqV6{KeLK{ z|0}}yff%aR{ WZ5Y)K54tW5<{KJ|x)`wG|2F~S-*%D! literal 0 HcmV?d00001 diff --git a/tests/resources/image/whiteCropped.png b/tests/resources/image/whiteCropped.png new file mode 100644 index 0000000000000000000000000000000000000000..fb18be863acb64eb00c5201d7b633c9d7ed1009e GIT binary patch literal 131 zcmeAS@N?(olHy`uVBq!ia0vp^DIm-NBp5u zzFuJjPvPcQSA1KRgg@?!Nq2vi<6vc{D8RwO)aamqojP%yOXx7m_RKxI_JU0JboFyt I=akR{0R5>YPXGV_ literal 0 HcmV?d00001 diff --git a/tests/resources/white.jpg/white.png b/tests/resources/white.jpg/white.png new file mode 100644 index 0000000000000000000000000000000000000000..4849863e890063b6d48b1d2c8691eebde0cbdc63 GIT binary patch literal 765 zcmeAS@N?(olHy`uVBq!ia0y~yV4MKNIvhX&h7)&o$pIT$Gwvl3(N)w?_jgDGZWyEG@~%F9OSk%AKpD#B6 zO6yjIM3lIs7AF^F7L;V>=P@vF%sj23sk!0Ob$xyP>)IZkmvv8`Kd*Vs``md}hP?S4 zAE&R^*}=fTWaa7N7*cWT?KN*dCr62vi@TJjx2v4H^Pf*v!f}eXWdVorWHYtr(N1&! zP4-jqoTT!yf7Yg7S?j$`w`K4CV#LU(q~O59($T;mD4^ibz`-E^72yz2U}AECiZDSH zfJGR{(Za+6HyLObBiv-5?O>~6b|D None: image = Image.from_png_file(resolve_resource_path("image/original.png")) image2 = image.flip_horizontally().flip_horizontally() assert image == image2 + + +class TestCrop: + def test_should_crop_jpg_image(self) -> None: + image = Image.from_jpeg_file(resolve_resource_path("image/white.jpg")) + image = image.crop(0, 0, 100, 100) + image2 = Image.from_jpeg_file(resolve_resource_path("image/whiteCropped.jpg")) + assert image == image2 + + def test_should_crop_png_image(self) -> None: + image = Image.from_png_file(resolve_resource_path("image/white.png")) + image = image.crop(0, 0, 100, 100) + image2 = Image.from_png_file(resolve_resource_path("image/whiteCropped.png")) + assert image == image2