fix: optimized output for irc and ansi, readme and workflow update
This commit is contained in:
+2
-1
@@ -1 +1,2 @@
|
||||
CLAUDE.md
|
||||
CLAUDE.md
|
||||
src/
|
||||
|
||||
@@ -19,6 +19,8 @@ An example workflow is provided in `workflows/mircify_example_workflow.json`.
|
||||
|
||||
At the moment this example is using qwen image (gguf), lightning 4 step lora with RES4LYF samplers. However any model that is decent at making pixel ansi style art can suffice.
|
||||
|
||||
It will save the irc and ansi data to the [png exif data](#irc-png-exporter) and also to [file](#irc-text-saver).
|
||||
|
||||
## IRC Output
|
||||
|
||||
Pasting the results of the created `.txt` file into IRC, we should be able to see the IRC art rendered in the client.
|
||||
@@ -44,6 +46,8 @@ or display it with `less -R` to preserve colors:
|
||||
less -R output/irc_art/your_ansi_file.txt
|
||||
```
|
||||
|
||||

|
||||
|
||||
## Features
|
||||
|
||||
- **Universal Image Support**: Works with any image dimensions, but remember the IRC 512 byte limit per line.
|
||||
@@ -202,6 +206,7 @@ For more information about how IRC uses colors refer to these resources:
|
||||
- torch
|
||||
- numpy
|
||||
- scikit-learn
|
||||
- Pillow
|
||||
|
||||
## Credits
|
||||
|
||||
|
||||
+2
-1
@@ -1,3 +1,4 @@
|
||||
torch>=1.9.0
|
||||
numpy>=1.21.0
|
||||
scikit-learn>=1.0.0
|
||||
scikit-learn>=1.0.0
|
||||
Pillow>=8.0.0
|
||||
+66
-16
@@ -192,12 +192,13 @@ class IRCFormatter(TextFormatter):
|
||||
|
||||
@staticmethod
|
||||
def format_line(line_colors: List[Union[int, Tuple[int, int]]]) -> str:
|
||||
"""Format a line of IRC color codes with compression."""
|
||||
"""Format a line of IRC color codes with comprehensive duplicate prevention."""
|
||||
if not line_colors:
|
||||
return ""
|
||||
|
||||
result = []
|
||||
i = 0
|
||||
last_color_code = None # Track the last color code to prevent duplicates
|
||||
|
||||
while i < len(line_colors):
|
||||
color_entry = line_colors[i]
|
||||
@@ -207,23 +208,47 @@ class IRCFormatter(TextFormatter):
|
||||
top_color, bottom_color = color_entry
|
||||
|
||||
if top_color == bottom_color:
|
||||
# Compress consecutive identical blocks
|
||||
# Same colors - treat as spaces with background color
|
||||
count = 1
|
||||
while (i + count < len(line_colors) and
|
||||
isinstance(line_colors[i + count], tuple) and
|
||||
line_colors[i + count] == color_entry):
|
||||
count += 1
|
||||
|
||||
result.append(IRCFormatter.format_color_code(top_color) + (SPACE_CHAR * count))
|
||||
color_code = IRCFormatter.format_color_code(top_color)
|
||||
if color_code != last_color_code:
|
||||
result.append(color_code + (SPACE_CHAR * count))
|
||||
last_color_code = color_code
|
||||
else:
|
||||
# Same color code as previous, just add spaces without color code
|
||||
result.append(SPACE_CHAR * count)
|
||||
i += count
|
||||
else:
|
||||
# Different colors - use half block character
|
||||
result.append(IRCFormatter.format_color_code(top_color, bottom_color) + HALF_BLOCK_CHAR)
|
||||
i += 1
|
||||
# Different colors - check for consecutive identical half-block patterns
|
||||
count = 1
|
||||
while (i + count < len(line_colors) and
|
||||
isinstance(line_colors[i + count], tuple) and
|
||||
line_colors[i + count] == color_entry):
|
||||
count += 1
|
||||
|
||||
color_code = IRCFormatter.format_color_code(top_color, bottom_color)
|
||||
if color_code != last_color_code:
|
||||
result.append(color_code + (HALF_BLOCK_CHAR * count))
|
||||
last_color_code = color_code
|
||||
else:
|
||||
# Same color code as previous, just add characters without color code
|
||||
result.append(HALF_BLOCK_CHAR * count)
|
||||
i += count
|
||||
else:
|
||||
# Full-block mode
|
||||
# Full-block mode - treat as spaces with background color
|
||||
count = IRCFormatter.count_consecutive(line_colors, i)
|
||||
result.append(IRCFormatter.format_color_code(color_entry) + (SPACE_CHAR * count))
|
||||
color_code = IRCFormatter.format_color_code(color_entry)
|
||||
if color_code != last_color_code:
|
||||
result.append(color_code + (SPACE_CHAR * count))
|
||||
last_color_code = color_code
|
||||
else:
|
||||
# Same color code as previous, just add spaces without color code
|
||||
result.append(SPACE_CHAR * count)
|
||||
i += count
|
||||
|
||||
return ''.join(result)
|
||||
@@ -250,12 +275,13 @@ class ANSIFormatter(TextFormatter):
|
||||
return f"\033[38;5;{top_ansi};48;5;{bottom_ansi}m{HALF_BLOCK_CHAR}"
|
||||
|
||||
def format_line(self, line_colors: List[Union[int, Tuple[int, int]]]) -> str:
|
||||
"""Format a line of ANSI color codes with compression."""
|
||||
"""Format a line of ANSI color codes with comprehensive duplicate prevention."""
|
||||
if not line_colors:
|
||||
return ""
|
||||
|
||||
result = []
|
||||
i = 0
|
||||
last_ansi_code = None # Track the last ANSI code to prevent duplicates
|
||||
|
||||
while i < len(line_colors):
|
||||
color_entry = line_colors[i]
|
||||
@@ -265,7 +291,7 @@ class ANSIFormatter(TextFormatter):
|
||||
top_color, bottom_color = color_entry
|
||||
|
||||
if top_color == bottom_color:
|
||||
# Same color - compress
|
||||
# Same colors - treat as background spaces
|
||||
count = 1
|
||||
while (i + count < len(line_colors) and
|
||||
isinstance(line_colors[i + count], tuple) and
|
||||
@@ -273,19 +299,43 @@ class ANSIFormatter(TextFormatter):
|
||||
count += 1
|
||||
|
||||
ansi_color = self.get_ansi_color(top_color)
|
||||
result.append(self.format_background(ansi_color, count))
|
||||
ansi_code = f"\033[48;5;{ansi_color}m"
|
||||
if ansi_code != last_ansi_code:
|
||||
result.append(ansi_code + (SPACE_CHAR * count))
|
||||
last_ansi_code = ansi_code
|
||||
else:
|
||||
# Same ANSI code as previous, just add spaces without code
|
||||
result.append(SPACE_CHAR * count)
|
||||
i += count
|
||||
else:
|
||||
# Different colors - half block
|
||||
# Different colors - check for consecutive identical patterns
|
||||
count = 1
|
||||
while (i + count < len(line_colors) and
|
||||
isinstance(line_colors[i + count], tuple) and
|
||||
line_colors[i + count] == color_entry):
|
||||
count += 1
|
||||
|
||||
top_ansi = self.get_ansi_color(top_color)
|
||||
bottom_ansi = self.get_ansi_color(bottom_color)
|
||||
result.append(self.format_half_block(top_ansi, bottom_ansi))
|
||||
i += 1
|
||||
ansi_code = f"\033[38;5;{top_ansi};48;5;{bottom_ansi}m"
|
||||
if ansi_code != last_ansi_code:
|
||||
result.append(ansi_code + (HALF_BLOCK_CHAR * count))
|
||||
last_ansi_code = ansi_code
|
||||
else:
|
||||
# Same ANSI code as previous, just add characters without code
|
||||
result.append(HALF_BLOCK_CHAR * count)
|
||||
i += count
|
||||
else:
|
||||
# Full-block mode
|
||||
# Full-block mode - treat as background spaces
|
||||
count = ANSIFormatter.count_consecutive(line_colors, i)
|
||||
ansi_color = self.get_ansi_color(color_entry)
|
||||
result.append(self.format_background(ansi_color, count))
|
||||
ansi_code = f"\033[48;5;{ansi_color}m"
|
||||
if ansi_code != last_ansi_code:
|
||||
result.append(ansi_code + (SPACE_CHAR * count))
|
||||
last_ansi_code = ansi_code
|
||||
else:
|
||||
# Same ANSI code as previous, just add spaces without code
|
||||
result.append(SPACE_CHAR * count)
|
||||
i += count
|
||||
|
||||
result.append(ANSI_RESET)
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
{
|
||||
"id": "6a85ef9e-440c-47f8-b6cc-6a647c18839d",
|
||||
"revision": 0,
|
||||
"last_node_id": 93,
|
||||
"last_link_id": 156,
|
||||
"last_node_id": 94,
|
||||
"last_link_id": 159,
|
||||
"nodes": [
|
||||
{
|
||||
"id": 7,
|
||||
@@ -399,7 +399,7 @@
|
||||
"widget_ue_connectable": {}
|
||||
},
|
||||
"widgets_values": [
|
||||
817468956820710,
|
||||
462218769959024,
|
||||
"randomize",
|
||||
4,
|
||||
1,
|
||||
@@ -408,6 +408,157 @@
|
||||
1
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 91,
|
||||
"type": "IRC Text Saver",
|
||||
"pos": [
|
||||
1386.3250732421875,
|
||||
292.4225158691406
|
||||
],
|
||||
"size": [
|
||||
270,
|
||||
58
|
||||
],
|
||||
"flags": {},
|
||||
"order": 11,
|
||||
"mode": 0,
|
||||
"inputs": [
|
||||
{
|
||||
"name": "irc_text",
|
||||
"type": "STRING",
|
||||
"link": 155
|
||||
}
|
||||
],
|
||||
"outputs": [
|
||||
{
|
||||
"name": "file_path",
|
||||
"type": "STRING",
|
||||
"links": null
|
||||
}
|
||||
],
|
||||
"properties": {
|
||||
"aux_id": "ComfyUI-Mircify.git",
|
||||
"ver": "7560f88586f8cf1c4e67e706e79f3dfc3390f308",
|
||||
"Node name for S&R": "IRC Text Saver"
|
||||
},
|
||||
"widgets_values": [
|
||||
"irc_art_{TIMESTAMP}.txt"
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 93,
|
||||
"type": "IRC Text Saver",
|
||||
"pos": [
|
||||
1391.58154296875,
|
||||
407.7270812988281
|
||||
],
|
||||
"size": [
|
||||
270,
|
||||
58
|
||||
],
|
||||
"flags": {},
|
||||
"order": 12,
|
||||
"mode": 0,
|
||||
"inputs": [
|
||||
{
|
||||
"name": "irc_text",
|
||||
"type": "STRING",
|
||||
"link": 156
|
||||
}
|
||||
],
|
||||
"outputs": [
|
||||
{
|
||||
"name": "file_path",
|
||||
"type": "STRING",
|
||||
"links": null
|
||||
}
|
||||
],
|
||||
"properties": {
|
||||
"aux_id": "ComfyUI-Mircify.git",
|
||||
"ver": "7560f88586f8cf1c4e67e706e79f3dfc3390f308",
|
||||
"Node name for S&R": "IRC Text Saver"
|
||||
},
|
||||
"widgets_values": [
|
||||
"ansi_art_{TIMESTAMP}.txt"
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 76,
|
||||
"type": "UnetLoaderGGUF",
|
||||
"pos": [
|
||||
-125.99971008300781,
|
||||
-188.51158142089844
|
||||
],
|
||||
"size": [
|
||||
270,
|
||||
58
|
||||
],
|
||||
"flags": {},
|
||||
"order": 3,
|
||||
"mode": 0,
|
||||
"inputs": [],
|
||||
"outputs": [
|
||||
{
|
||||
"name": "MODEL",
|
||||
"type": "MODEL",
|
||||
"links": [
|
||||
134
|
||||
]
|
||||
}
|
||||
],
|
||||
"properties": {
|
||||
"cnr_id": "ComfyUI-GGUF",
|
||||
"ver": "d247022e3fa66851c5084cc251b076aab816423d",
|
||||
"Node name for S&R": "UnetLoaderGGUF"
|
||||
},
|
||||
"widgets_values": [
|
||||
"qwen/qwen-image-Q8_0.gguf"
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 94,
|
||||
"type": "IRC PNG Exporter",
|
||||
"pos": [
|
||||
1399.4827880859375,
|
||||
-166.5812225341797
|
||||
],
|
||||
"size": [
|
||||
270,
|
||||
334
|
||||
],
|
||||
"flags": {},
|
||||
"order": 13,
|
||||
"mode": 0,
|
||||
"inputs": [
|
||||
{
|
||||
"name": "image",
|
||||
"type": "IMAGE",
|
||||
"link": 159
|
||||
},
|
||||
{
|
||||
"name": "irc_text",
|
||||
"shape": 7,
|
||||
"type": "STRING",
|
||||
"link": 157
|
||||
},
|
||||
{
|
||||
"name": "ansi_text",
|
||||
"shape": 7,
|
||||
"type": "STRING",
|
||||
"link": 158
|
||||
}
|
||||
],
|
||||
"outputs": [],
|
||||
"properties": {
|
||||
"aux_id": "ComfyUI-Mircify.git",
|
||||
"ver": "2d649703ece193bb00fecca47f77c9a9e76dd3fc",
|
||||
"Node name for S&R": "IRC PNG Exporter"
|
||||
},
|
||||
"widgets_values": [
|
||||
true,
|
||||
"irc_art_{TIMESTAMP}.png"
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 6,
|
||||
"type": "CLIPTextEncode",
|
||||
@@ -459,43 +610,6 @@
|
||||
"color": "#232",
|
||||
"bgcolor": "#353"
|
||||
},
|
||||
{
|
||||
"id": 91,
|
||||
"type": "IRC Text Saver",
|
||||
"pos": [
|
||||
1386.3250732421875,
|
||||
292.4225158691406
|
||||
],
|
||||
"size": [
|
||||
270,
|
||||
58
|
||||
],
|
||||
"flags": {},
|
||||
"order": 12,
|
||||
"mode": 0,
|
||||
"inputs": [
|
||||
{
|
||||
"name": "irc_text",
|
||||
"type": "STRING",
|
||||
"link": 155
|
||||
}
|
||||
],
|
||||
"outputs": [
|
||||
{
|
||||
"name": "file_path",
|
||||
"type": "STRING",
|
||||
"links": null
|
||||
}
|
||||
],
|
||||
"properties": {
|
||||
"aux_id": "ComfyUI-Mircify.git",
|
||||
"ver": "7560f88586f8cf1c4e67e706e79f3dfc3390f308",
|
||||
"Node name for S&R": "IRC Text Saver"
|
||||
},
|
||||
"widgets_values": [
|
||||
"irc_art_{TIMESTAMP}.txt"
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 82,
|
||||
"type": "IRC Art Converter",
|
||||
@@ -522,21 +636,23 @@
|
||||
"name": "processed_image",
|
||||
"type": "IMAGE",
|
||||
"links": [
|
||||
142
|
||||
159
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "irc_text",
|
||||
"type": "STRING",
|
||||
"links": [
|
||||
155
|
||||
155,
|
||||
157
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "ansi_text",
|
||||
"type": "STRING",
|
||||
"links": [
|
||||
156
|
||||
156,
|
||||
158
|
||||
]
|
||||
}
|
||||
],
|
||||
@@ -552,105 +668,6 @@
|
||||
false,
|
||||
"perceptual_weighted"
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 93,
|
||||
"type": "IRC Text Saver",
|
||||
"pos": [
|
||||
1391.58154296875,
|
||||
407.7270812988281
|
||||
],
|
||||
"size": [
|
||||
270,
|
||||
58
|
||||
],
|
||||
"flags": {},
|
||||
"order": 13,
|
||||
"mode": 0,
|
||||
"inputs": [
|
||||
{
|
||||
"name": "irc_text",
|
||||
"type": "STRING",
|
||||
"link": 156
|
||||
}
|
||||
],
|
||||
"outputs": [
|
||||
{
|
||||
"name": "file_path",
|
||||
"type": "STRING",
|
||||
"links": null
|
||||
}
|
||||
],
|
||||
"properties": {
|
||||
"aux_id": "ComfyUI-Mircify.git",
|
||||
"ver": "7560f88586f8cf1c4e67e706e79f3dfc3390f308",
|
||||
"Node name for S&R": "IRC Text Saver"
|
||||
},
|
||||
"widgets_values": [
|
||||
"ansi_art_{TIMESTAMP}.txt"
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 80,
|
||||
"type": "PreviewImage",
|
||||
"pos": [
|
||||
1385.32958984375,
|
||||
-166.24484252929688
|
||||
],
|
||||
"size": [
|
||||
524.072998046875,
|
||||
389.5648498535156
|
||||
],
|
||||
"flags": {},
|
||||
"order": 11,
|
||||
"mode": 0,
|
||||
"inputs": [
|
||||
{
|
||||
"name": "images",
|
||||
"type": "IMAGE",
|
||||
"link": 142
|
||||
}
|
||||
],
|
||||
"outputs": [],
|
||||
"properties": {
|
||||
"cnr_id": "comfy-core",
|
||||
"ver": "0.3.52",
|
||||
"Node name for S&R": "PreviewImage"
|
||||
},
|
||||
"widgets_values": []
|
||||
},
|
||||
{
|
||||
"id": 76,
|
||||
"type": "UnetLoaderGGUF",
|
||||
"pos": [
|
||||
-125.99971008300781,
|
||||
-188.51158142089844
|
||||
],
|
||||
"size": [
|
||||
270,
|
||||
58
|
||||
],
|
||||
"flags": {},
|
||||
"order": 3,
|
||||
"mode": 0,
|
||||
"inputs": [],
|
||||
"outputs": [
|
||||
{
|
||||
"name": "MODEL",
|
||||
"type": "MODEL",
|
||||
"links": [
|
||||
134
|
||||
]
|
||||
}
|
||||
],
|
||||
"properties": {
|
||||
"cnr_id": "ComfyUI-GGUF",
|
||||
"ver": "d247022e3fa66851c5084cc251b076aab816423d",
|
||||
"Node name for S&R": "UnetLoaderGGUF"
|
||||
},
|
||||
"widgets_values": [
|
||||
"qwen/qwen-image-Q8_0.gguf"
|
||||
]
|
||||
}
|
||||
],
|
||||
"links": [
|
||||
@@ -734,14 +751,6 @@
|
||||
0,
|
||||
"MODEL"
|
||||
],
|
||||
[
|
||||
142,
|
||||
82,
|
||||
0,
|
||||
80,
|
||||
0,
|
||||
"IMAGE"
|
||||
],
|
||||
[
|
||||
150,
|
||||
8,
|
||||
@@ -765,6 +774,30 @@
|
||||
93,
|
||||
0,
|
||||
"STRING"
|
||||
],
|
||||
[
|
||||
157,
|
||||
82,
|
||||
1,
|
||||
94,
|
||||
1,
|
||||
"STRING"
|
||||
],
|
||||
[
|
||||
158,
|
||||
82,
|
||||
2,
|
||||
94,
|
||||
2,
|
||||
"STRING"
|
||||
],
|
||||
[
|
||||
159,
|
||||
82,
|
||||
0,
|
||||
94,
|
||||
0,
|
||||
"IMAGE"
|
||||
]
|
||||
],
|
||||
"groups": [],
|
||||
@@ -773,8 +806,8 @@
|
||||
"ds": {
|
||||
"scale": 0.8390545288824212,
|
||||
"offset": [
|
||||
108.16671263739013,
|
||||
536.0446891793314
|
||||
271.42065915743825,
|
||||
496.835589687672
|
||||
]
|
||||
},
|
||||
"frontendVersion": "1.23.4",
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 91 KiB After Width: | Height: | Size: 73 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 31 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 27 KiB After Width: | Height: | Size: 32 KiB |
Reference in New Issue
Block a user