-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Closes #158. ### Summary of Changes * New class `safeds.data.image.containers.Image` to store images * An `Image` can be created from and saved to JPEG and PNG files * Methods that create a plot for `Table` and `Column` now return an `Image` instead of plotting them directly in an interactive environment * An `Image` can be displayed in an interactive environment --------- Co-authored-by: megalinter-bot <[email protected]>
- Loading branch information
1 parent
26eee03
commit ed7ae34
Showing
18 changed files
with
485 additions
and
113 deletions.
There are no files selected for viewing
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
"""Work with image data.""" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
"""Classes that can store image data.""" | ||
|
||
from ._image import Image | ||
|
||
__all__ = [ | ||
"Image", | ||
] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,153 @@ | ||
from __future__ import annotations | ||
|
||
import io | ||
from pathlib import Path | ||
from typing import BinaryIO | ||
|
||
from PIL.Image import Image as PillowImage | ||
from PIL.Image import open as open_image | ||
|
||
from safeds.data.image.typing import ImageFormat | ||
|
||
|
||
class Image: | ||
""" | ||
A container for image data. | ||
Parameters | ||
---------- | ||
data : BinaryIO | ||
The image data as bytes. | ||
""" | ||
|
||
@staticmethod | ||
def from_jpeg_file(path: str) -> Image: | ||
""" | ||
Create an image from a JPEG file. | ||
Parameters | ||
---------- | ||
path : str | ||
The path to the JPEG file. | ||
Returns | ||
------- | ||
image : Image | ||
The image. | ||
""" | ||
return Image( | ||
data=Path(path).open("rb"), | ||
format_=ImageFormat.JPEG, | ||
) | ||
|
||
@staticmethod | ||
def from_png_file(path: str) -> Image: | ||
""" | ||
Create an image from a PNG file. | ||
Parameters | ||
---------- | ||
path : str | ||
The path to the PNG file. | ||
Returns | ||
------- | ||
image : Image | ||
The image. | ||
""" | ||
return Image( | ||
data=Path(path).open("rb"), | ||
format_=ImageFormat.PNG, | ||
) | ||
|
||
def __init__(self, data: BinaryIO, format_: ImageFormat): | ||
data.seek(0) | ||
|
||
self._image: PillowImage = open_image(data, formats=[format_.value]) | ||
self._format: ImageFormat = format_ | ||
|
||
# ------------------------------------------------------------------------------------------------------------------ | ||
# Properties | ||
# ------------------------------------------------------------------------------------------------------------------ | ||
|
||
@property | ||
def format(self) -> ImageFormat: | ||
""" | ||
Get the image format. | ||
Returns | ||
------- | ||
format : ImageFormat | ||
The image format. | ||
""" | ||
return self._format | ||
|
||
# ------------------------------------------------------------------------------------------------------------------ | ||
# Conversion | ||
# ------------------------------------------------------------------------------------------------------------------ | ||
|
||
def to_jpeg_file(self, path: str) -> None: | ||
""" | ||
Save the image as a JPEG file. | ||
Parameters | ||
---------- | ||
path : str | ||
The path to the JPEG file. | ||
""" | ||
Path(path).parent.mkdir(parents=True, exist_ok=True) | ||
self._image.save(path, format="jpeg") | ||
|
||
def to_png_file(self, path: str) -> None: | ||
""" | ||
Save the image as a PNG file. | ||
Parameters | ||
---------- | ||
path : str | ||
The path to the PNG file. | ||
""" | ||
Path(path).parent.mkdir(parents=True, exist_ok=True) | ||
self._image.save(path, format="png") | ||
|
||
# ------------------------------------------------------------------------------------------------------------------ | ||
# IPython integration | ||
# ------------------------------------------------------------------------------------------------------------------ | ||
|
||
def _repr_jpeg_(self) -> bytes | None: | ||
""" | ||
Return a JPEG image as bytes. | ||
If the image is not a JPEG, return None. | ||
Returns | ||
------- | ||
jpeg : bytes | ||
The image as JPEG. | ||
""" | ||
if self._format != ImageFormat.JPEG: | ||
return None | ||
|
||
buffer = io.BytesIO() | ||
self._image.save(buffer, format="jpeg") | ||
buffer.seek(0) | ||
return buffer.read() | ||
|
||
def _repr_png_(self) -> bytes | None: | ||
""" | ||
Return a PNG image as bytes. | ||
If the image is not a PNG, return None. | ||
Returns | ||
------- | ||
png : bytes | ||
The image as PNG. | ||
""" | ||
if self._format != ImageFormat.PNG: | ||
return None | ||
|
||
buffer = io.BytesIO() | ||
self._image.save(buffer, format="png") | ||
buffer.seek(0) | ||
return buffer.read() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
"""Types used to distinguish different image formats.""" | ||
|
||
from ._image_format import ImageFormat | ||
|
||
__all__ = [ | ||
"ImageFormat", | ||
] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
from enum import Enum | ||
|
||
|
||
class ImageFormat(Enum): | ||
"""Images formats supported by us.""" | ||
|
||
JPEG = "jpeg" | ||
PNG = "png" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.