There is no (built-in)You can use os.PathLike. Various applications and libraries roll their own with a Union. IfHowever, if we were to abide by the protocol of the inner open() call, then a union of a Path and a strPathLike is incorrect, because it can also take a file-like:
But I consider all of that to be a bit much for this application, and would constrain it to PathPathLike for simplicity and clarity.
from os import PathLike
from pathlib import Path
import PIL.Image
import numpy as np
CHARSET = (
"@$B%8&WM#*oahkbdpqwm"
"ZO0QLCJUYXzcvunxrjft"
"/\|()1{}[]?-_+~<>i!l"
"I;:,\"^`'. "
)
def resize(image: PIL.Image.Image, new_width: int = 300) -> PIL.Image.Image:
width, height = image.size
new_height = new_width * height / width / 2.5
return image.resize((round(new_width), round(new_height)))
def pixel_to_ascii(pixels: np.ndarray, light_mode: bool = True) -> str:
direction = 1 if light_mode else -1
charset_str = CHARSET[::direction]
charset = np.array(tuple(charset_str), dtype='U1')
minp = pixels.min()
maxp = pixels.max()
scaled = (pixels - minp) / (maxp - minp) * (len(CHARSET) - 1)
indices = np.around(scaled).astype(int)
ascii_array = charset[indices]
rows = ascii_array.view(f'U{pixels.shape[1]}')[:, 0]
return '\n'.join(rows)
def convert(path: PathPathLike) -> str:
greyscale_image = resize(PIL.Image.open(path).convert('F'))
return pixel_to_ascii(np.array(greyscale_image))
def main() -> None:
ascii_img = convert(Path('archived/image2l.png'))
print(ascii_img)
if __name__ == '__main__':
main()