Skip to content

Commit

Permalink
working on testing transparency
Browse files Browse the repository at this point in the history
  • Loading branch information
lostways committed Dec 27, 2023
1 parent 6ff3a53 commit 6918782
Show file tree
Hide file tree
Showing 4 changed files with 145 additions and 27 deletions.
15 changes: 7 additions & 8 deletions examples/convert_img.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,16 +25,15 @@
img_path = Path(args.img_path).as_posix()
img = Image.open(img_path)

"""
img: Image.Image = Image.new("RGBA", (4, 4), (255, 0, 0, 255))
img: Image.Image = Image.new("RGBA", (5, 7), (255, 0, 0, 255))
img.putpixel((0, 0), (255, 0, 0, 0))
img.putpixel((0, 3), (255, 0, 0, 0))
img.putpixel((3, 0), (255, 0, 0, 0))
img.putpixel((3, 3), (255, 0, 0, 0))
img.putpixel((0, 6), (255, 0, 0, 0))
img.putpixel((4, 0), (255, 0, 0, 0))
img.putpixel((4, 6), (255, 0, 0, 0))

img_data_list = list(img.getdata())
print(np.array(img_data_list).reshape(4,4,4))
"""
print(np.array(img_data_list).reshape(5,7,4))

# convert to ansi
out = convert_img(
img=img,
Expand All @@ -44,5 +43,5 @@
)

# print to terminal
#print(repr(out))
print(repr(out))
print(out)
25 changes: 12 additions & 13 deletions src/pil2ansi.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,10 +32,10 @@ def pixel_to_color(self, pixel_fg: PIXEL_RGBA, pixel_bg: PIXEL_RGBA) -> str:
r, g, b, a = pixel_fg
r2, g2, b2, a2 = pixel_bg

format1 = 1 if a == 0 else 2 # 2 is RGB, 1 is transparent
format2 = 1 if a2 == 0 else 2 # 2 is RGB, 1 is transparent
fg_out = f"\033[38;2;{r};{g};{b};" if a != 0 else "\033[38;1;"
bg_out = f"48;2;{r2};{g2};{b2}m" if a2 != 0 else "48;1m"

return f"\033[38;{format1};{r};{g};{b};48;{format2};{r2};{g2};{b2}m"
return f"{fg_out}{bg_out}"


@dataclass
Expand All @@ -47,9 +47,6 @@ def pixel_to_color(self, pixel_fg: PIXEL_LA, pixel_bg: PIXEL_LA) -> str:
p1, a1 = pixel_fg
p2, a2 = pixel_bg

format1 = 1 if a1 == 0 else 5 # 5 is 8-bit, 1 is transparent
format2 = 1 if a2 == 0 else 5 # 5 is 8-bit, 1 is transparent

num_values = 23

if self.invert == True:
Expand All @@ -59,7 +56,10 @@ def pixel_to_color(self, pixel_fg: PIXEL_LA, pixel_bg: PIXEL_LA) -> str:
val_fg = 232 + int(p1 * num_values / 255)
val_bg = 232 + int(p2 * num_values / 255)

return f"\033[38;{format1};{val_fg};48;{format2};{val_bg}m"
fg_out = f"\033[38;5;{val_fg};" if a1 != 0 else "\033[38;1;"
bg_out = f"48;5;{val_bg}m" if a2 != 0 else "48;1m"

return f"{fg_out}{bg_out}"


@dataclass
Expand Down Expand Up @@ -111,8 +111,8 @@ def convert_img(
img = img.resize((new_width, new_height), resample=Image.NEAREST)

# crop image to terminal width
if new_width > TERMINAL_WIDTH:
img = img.crop((0, 0, TERMINAL_WIDTH, new_height))
if img.width > TERMINAL_WIDTH:
img = img.crop((0, 0, TERMINAL_WIDTH, img.height))

pixels = img.getdata()

Expand All @@ -132,17 +132,16 @@ def convert_img(
if i < img.height - 1:
pixel_bg = pixels[(i + 1) * img.width + j]
else:
pixel_bg = tuple(
[255 for _ in pixel_fg[:-1]] + [0]
) # makebg transparent on last row
pixel_bg = tuple(pixel_fg[:-1] + (0,)) # makebg transparent on last row

if alpha == False:
pixel_fg = tuple(pixel_fg[:-1] + (255,))
pixel_bg = tuple(pixel_bg[:-1] + (255,))

if pixel_fg[-1] == 0 and pixel_bg[-1] == 0:
ascii_str += f"{reset_char}{transparent_char}"
elif pixel_fg[-1] == 0:
ascii_str += f"{reset_char}{palette.pixel_to_color(pixel_fg=pixel_bg, pixel_bg=pixel_bg)}"
ascii_str += f"{reset_char}{palette.pixel_to_color(pixel_fg=pixel_bg, pixel_bg=pixel_fg)}"
if palette != Palettes.ascii:
ascii_str += unicode_lower_char
else:
Expand Down
120 changes: 120 additions & 0 deletions tests/test_convert_img.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
from pil2ansi import convert_img, Palettes
from PIL import Image

class TestConvertImg:
reset_char: str = "\033[0m"
transparent_char: str = f"{reset_char} "
unicode_upper_char: str = "\u2580"
unicode_lower_char: str = "\u2584"

RGBA_red_out: str = f"{reset_char}\033[38;2;255;0;0;48;2;255;0;0m{unicode_upper_char}"
RGBA_red_end_row_out: str = f"{reset_char}\033[38;2;255;0;0;48;1m{unicode_upper_char}"
RGBA_red_alpha_upper_out: str = f"{reset_char}\033[38;2;255;0;0;48;1m{unicode_lower_char}"
RGBA_red_alpha_lower_out: str = f"{reset_char}\033[38;2;255;0;0;48;1m{unicode_upper_char}"

LA_red_out: str = f"{reset_char}\033[38;5;238;48;5;238m{unicode_upper_char}"
LA_red_end_row_out: str = f"{reset_char}\033[38;5;238;48;1m{unicode_upper_char}"
LA_red_alpha_upper_out: str = f"{reset_char}\033[38;5;238;48;1m{unicode_lower_char}"
LA_red_alpha_lower_out: str = f"{reset_char}\033[38;5;238;48;1m{unicode_upper_char}"

end_row_out: str = f"{reset_char}\n"

def test_convert_img_color_2x2(self):
img: Image.Image = Image.new("RGBA", (2, 2), (255, 0, 0, 255))
expected_out: str = self.RGBA_red_out * 2 + self.end_row_out
out = convert_img(img, Palettes.color)

assert len(img.getdata()) == 4
assert img.width == 2
assert out == expected_out

def test_convert_img_color_4x4(self):
img: Image.Image = Image.new("RGBA", (4, 4), (255, 0, 0, 255))
expected_out: str = (self.RGBA_red_out * 4 + self.end_row_out) * 2
out = convert_img(img, Palettes.color)

assert len(img.getdata()) == 16
assert img.width == 4
assert out == expected_out

def test_convert_img_color_5x7(self):
img: Image.Image = Image.new("RGBA", (5, 7), (255, 0, 0, 255))
expected_out: str = (self.RGBA_red_out * 5 + self.end_row_out) * 3
expected_out += self.RGBA_red_end_row_out * 5 + self.end_row_out
out = convert_img(img, Palettes.color)

assert len(img.getdata()) == 35
assert img.width == 5
assert out == expected_out

def test_convert_img_color_alpha_4x4(self):
img: Image.Image = Image.new("RGBA", (4, 4), (255, 0, 0, 255))
img.putpixel((0, 0), (255, 0, 0, 0))
img.putpixel((0, 3), (255, 0, 0, 0))
img.putpixel((3, 0), (255, 0, 0, 0))
img.putpixel((3, 3), (255, 0, 0, 0))

expected_out: str = (
self.RGBA_red_alpha_upper_out
+ (self.RGBA_red_out * 2)
+ self.RGBA_red_alpha_upper_out
+ self.end_row_out
)
expected_out += (
self.RGBA_red_alpha_lower_out
+ (self.RGBA_red_out * 2)
+ self.RGBA_red_alpha_lower_out
+ self.end_row_out
)
out = convert_img(img, Palettes.color, alpha=True)

assert len(img.getdata()) == 16
assert img.width == 4
assert out == expected_out

def test_convert_img_color_alpha_5x7(self):
img: Image.Image = Image.new("RGBA", (5, 7), (255, 0, 0, 255))
img.putpixel((0, 0), (255, 0, 0, 0))
img.putpixel((0, 6), (255, 0, 0, 0))
img.putpixel((4, 0), (255, 0, 0, 0))
img.putpixel((4, 6), (255, 0, 0, 0))

expected_out: str = (
self.RGBA_red_alpha_upper_out
+ (self.RGBA_red_out * 3)
+ self.RGBA_red_alpha_upper_out
+ self.end_row_out
)
expected_out += (
(self.RGBA_red_out * 5)
+ self.end_row_out
) * 2
expected_out += (
self.transparent_char
+ (self.RGBA_red_alpha_lower_out * 3)
+ self.transparent_char
+ self.end_row_out
)
out = convert_img(img, Palettes.color, alpha=True)
print(repr(expected_out))
print("\n")
print(repr(out))
print(expected_out)
print("\n")
print(out)

assert len(img.getdata()) == 35
assert img.width == 5
assert out == expected_out

def test_convert_img_grayscale_2x2(self):
img: Image.Image = Image.new("RGBA", (2, 2), (255, 0, 0, 255))
expected_out: str = self.LA_red_out * 2 + self.end_row_out
out = convert_img(img, Palettes.grayscale)

assert len(img.getdata()) == 4
assert img.width == 2
assert out == expected_out



12 changes: 6 additions & 6 deletions tests/test_palettes.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,16 +28,16 @@ def test_pixel_to_color(self):
assert palette.pixel_to_color((0, 255), (127, 255)) == "\033[38;5;232;48;5;243m"
assert palette.pixel_to_color((255, 255), (127, 255)) == "\033[38;5;255;48;5;243m"
assert palette.pixel_to_color((127, 255), (127, 255)) == "\033[38;5;243;48;5;243m"
assert palette.pixel_to_color((127, 0), (127, 255)) == "\033[38;1;243;48;5;243m"
assert palette.pixel_to_color((0, 255), (127, 0)) == "\033[38;5;232;48;1;243m"
assert palette.pixel_to_color((127, 0), (127, 255)) == "\033[38;1;48;5;243m"
assert palette.pixel_to_color((0, 255), (127, 0)) == "\033[38;5;232;48;1m"

def test_pixel_to_char_inverted(self):
palette = PaletteGrayscale(invert=True)
assert palette.pixel_to_color((0, 255), (127, 255)) == "\033[38;5;255;48;5;244m"
assert palette.pixel_to_color((255, 255), (127, 255)) == "\033[38;5;232;48;5;244m"
assert palette.pixel_to_color((127, 255), (127, 255)) == "\033[38;5;244;48;5;244m"
assert palette.pixel_to_color((127, 0), (127, 255)) == "\033[38;1;244;48;5;244m"
assert palette.pixel_to_color((0, 255), (127, 0)) == "\033[38;5;255;48;1;244m"
assert palette.pixel_to_color((127, 0), (127, 255)) == "\033[38;1;48;5;244m"
assert palette.pixel_to_color((0, 255), (127, 0)) == "\033[38;5;255;48;1m"


class TestPaletteColor:
Expand All @@ -55,10 +55,10 @@ def test_pixel_to_char(self):

assert (
palette.pixel_to_color((255, 127, 255, 0), (255, 255, 0, 255))
== "\033[38;1;255;127;255;48;2;255;255;0m"
== "\033[38;1;48;2;255;255;0m"
)

assert (
palette.pixel_to_color((255, 127, 255, 255), (255, 255, 0, 0))
== "\033[38;2;255;127;255;48;1;255;255;0m"
== "\033[38;2;255;127;255;48;1m"
)

0 comments on commit 6918782

Please sign in to comment.