forked from filliptm/ComfyUI_Fill-Nodes
-
Notifications
You must be signed in to change notification settings - Fork 0
/
fl_ascii.py
103 lines (87 loc) · 3.09 KB
/
fl_ascii.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
from PIL import Image, ImageDraw, ImageFont
import matplotlib.font_manager
import numpy as np
import torch
import sys
class FL_Ascii:
def __init__(self):
pass
@classmethod
def INPUT_TYPES(s):
font_list = [x.split('/')[-1] for x in matplotlib.font_manager.findSystemFonts(fontpaths=None, fontext="ttf" )]
return {
"required": {
"image": ("IMAGE",),
"spacing": (
"INT",
{
"default": 20,
"min": 4,
"max": 100,
"step": 2,
},
),
"font_size": (
"INT",
{
"default": 20,
"min": 4,
"max": 100,
"step": 2,
},
),
"font_name": (font_list,),
"characters": (
"STRING",
{
"default": "",
"description": "characters to use",
},
),
},
}
RETURN_TYPES = ("IMAGE",)
FUNCTION = "apply_ascii_art_effect"
CATEGORY = "🏵️Fill Nodes"
def apply_ascii_art_effect(
self,
image: torch.Tensor,
spacing: int,
font_size: int,
font_name: str,
characters,
):
batch_size, height, width, channels = image.shape
result = torch.zeros_like(image)
for b in range(batch_size):
img_b = image[b] * 255.0
img_b = Image.fromarray(img_b.numpy().astype("uint8"), "RGB")
result_b = ascii_art_effect(img_b, spacing, font_size, font_name, characters)
result_b = torch.tensor(np.array(result_b)) / 255.0
result[b] = result_b
# Update the print log
progress = (b + 1) / batch_size * 100
sys.stdout.write(f"\rProcessing images: {progress:.2f}%")
sys.stdout.flush()
# Print a new line after the progress log
print()
return (result,)
def ascii_art_effect(image: torch.Tensor, spacing: int, font_size: int, font_name: str, characters):
chars = characters
small_image = image.resize((image.size[0] // spacing, image.size[1] // spacing), Image.Resampling.NEAREST)
def get_char(value):
return chars[value * len(chars) // 256]
ascii_image = Image.new("RGB", image.size, (0, 0, 0))
font = ImageFont.truetype(font_name, font_size)
draw_image = ImageDraw.Draw(ascii_image)
for i in range(small_image.height):
for j in range(small_image.width):
r, g, b = small_image.getpixel((j, i))
k = (r + g + b) // 3
draw_image.text(
(j * spacing, i * spacing),
get_char(k),
font=font,
fill=(r, g, b)
)
return ascii_image