init
This commit is contained in:
parent
89ca008b87
commit
0dc0b7dc9b
10
README.md
10
README.md
|
@ -1,3 +1,13 @@
|
||||||
# thermatext
|
# thermatext
|
||||||
|
|
||||||
fancy name, QL-570 text formater
|
fancy name, QL-570 text formater
|
||||||
|
|
||||||
|
using gpt i got a shell script and then a python one. the python tries to detect letter width and maximise it to fit the label printer constraints (62mm width)
|
||||||
|
|
||||||
|
TDLR
|
||||||
|
`sudo brother_ql -b pyusb --model QL-570 -p usb://0x04f9:0x2028/000M12345678 print -l 62 logo.png`
|
||||||
|
|
||||||
|
TODO:
|
||||||
|
- use as printer
|
||||||
|
- fix missing font defentions fail to take into account letter width
|
||||||
|
- telegram bot (!)
|
||||||
|
|
33
text_to_image.sh
Executable file
33
text_to_image.sh
Executable file
|
@ -0,0 +1,33 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
if [ -z "$1" ]; then
|
||||||
|
echo "Usage: $0 <text_string>"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
text_string="$1"
|
||||||
|
filename="$(echo "$text_string" | tr ' ' '_').png"
|
||||||
|
|
||||||
|
# Set the desired image width and calculate the height
|
||||||
|
image_width=200
|
||||||
|
image_height=$((image_width / 4))
|
||||||
|
|
||||||
|
# Calculate the point size based on the length of the text string
|
||||||
|
point_size=$((image_width / ${#text_string} * 13 / 10))
|
||||||
|
|
||||||
|
echo "font_size ${point_size}"
|
||||||
|
# Set the desired font
|
||||||
|
font_file="/home/devdesk/.local/share/fonts/5x5_pixel.ttf"
|
||||||
|
|
||||||
|
convert -background white -fill black -font "$font_file" -pointsize "$point_size" \
|
||||||
|
-size "${image_width}x${image_height}" -gravity Center label:"$text_string" "$filename"
|
||||||
|
|
||||||
|
echo "PNG file created: $filename"
|
||||||
|
|
||||||
|
if [[ "$2" == "debug" ]]; then
|
||||||
|
echo "Debug mode detected, skipping print."
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
sudo brother_ql -b pyusb --model QL-570 -p usb://0x04f9:0x2028/000M6Z401370 --debug print -l 62 $filename
|
113
thermatext.py
Executable file
113
thermatext.py
Executable file
|
@ -0,0 +1,113 @@
|
||||||
|
#!/usr/bin/env python3
|
||||||
|
import os
|
||||||
|
import sys
|
||||||
|
from PIL import Image, ImageDraw, ImageFont
|
||||||
|
import textwrap
|
||||||
|
|
||||||
|
MAX_FONT_SIZE = 15 # Maximum font size
|
||||||
|
WORD_SPACING = 10 # Word spacing in pixels
|
||||||
|
SIDE_SPACING = 3 # Space from image sides in pixels
|
||||||
|
TOP_BOTTOM_SPACING = 10 # Space from top and bottom of image in pixels
|
||||||
|
|
||||||
|
def calculate_font_size(text, image_size, font_path):
|
||||||
|
# Create a dummy image to get the text size
|
||||||
|
dummy_img = Image.new('RGB', (1, 1))
|
||||||
|
draw = ImageDraw.Draw(dummy_img)
|
||||||
|
# Start from a large font size
|
||||||
|
font_size = 200
|
||||||
|
font = ImageFont.truetype(font_path, font_size)
|
||||||
|
# Decrease the font size until the text fits the image width
|
||||||
|
while draw.textbbox((0, 0), text, font)[2] > image_size[0] - 2 * SIDE_SPACING:
|
||||||
|
font_size -= 1
|
||||||
|
font = ImageFont.truetype(font_path, font_size)
|
||||||
|
return font_size
|
||||||
|
|
||||||
|
def split_text(text, max_font_size, image_size, font_path):
|
||||||
|
# Wrap the text based on word spacing and /n
|
||||||
|
wrapper = WordSpacingTextWrapper(width=image_size[0], word_spacing=WORD_SPACING)
|
||||||
|
wrapped_text = []
|
||||||
|
for line in text.split('\n'):
|
||||||
|
lines = wrapper.wrap(line)
|
||||||
|
wrapped_text.extend(lines)
|
||||||
|
return wrapped_text
|
||||||
|
|
||||||
|
class WordSpacingTextWrapper(textwrap.TextWrapper):
|
||||||
|
def __init__(self, word_spacing=0, **kwargs):
|
||||||
|
super().__init__(**kwargs)
|
||||||
|
self.word_spacing = word_spacing
|
||||||
|
|
||||||
|
def _wrap_chunks(self, chunks):
|
||||||
|
# Add word spacing between chunks
|
||||||
|
chunks = super()._wrap_chunks(chunks)
|
||||||
|
lines = []
|
||||||
|
for i, line in enumerate(chunks):
|
||||||
|
if i < len(chunks) - 1:
|
||||||
|
line += ' ' * self.word_spacing
|
||||||
|
lines.append(line)
|
||||||
|
return lines
|
||||||
|
|
||||||
|
def main(text, debug=False):
|
||||||
|
image_width = 200
|
||||||
|
image_height = image_width // 4
|
||||||
|
image_size = (image_width, image_height)
|
||||||
|
font_path = "/home/devdesk/.local/share/fonts/5x5_pixel.ttf"
|
||||||
|
|
||||||
|
text_for_filename = text.replace(' ', '_').replace('/', '_').replace('\n', '')
|
||||||
|
filename = f"labels/{text_for_filename}.png"
|
||||||
|
|
||||||
|
|
||||||
|
font_size = calculate_font_size(text, image_size, font_path)
|
||||||
|
|
||||||
|
# Split the text into multiple lines if the font size is less than 20
|
||||||
|
if font_size < 20:
|
||||||
|
lines = split_text(text, 20, image_size, font_path)
|
||||||
|
# Recalculate the font size and image height with the split text
|
||||||
|
font_size = calculate_font_size('\n'.join(lines), image_size, font_path)
|
||||||
|
num_lines = len(lines)
|
||||||
|
line_height = font_size
|
||||||
|
line_spacing = line_height // 2 # Adjust line spacing as needed
|
||||||
|
image_height = line_height * num_lines + 2 * TOP_BOTTOM_SPACING + (num_lines - 1) * line_spacing
|
||||||
|
image_size = (image_width, image_height)
|
||||||
|
|
||||||
|
else:
|
||||||
|
lines = [text]
|
||||||
|
num_lines = 1
|
||||||
|
line_height = font_size
|
||||||
|
line_spacing = line_height // 2 # Adjust line spacing as needed
|
||||||
|
image_height = line_height + 2 * TOP_BOTTOM_SPACING
|
||||||
|
|
||||||
|
# Create the image
|
||||||
|
img = Image.new('RGB', image_size, color='white')
|
||||||
|
d = ImageDraw.Draw(img)
|
||||||
|
font = ImageFont.truetype(font_path, font_size)
|
||||||
|
|
||||||
|
# Draw the text for each line
|
||||||
|
y = TOP_BOTTOM_SPACING
|
||||||
|
for line in lines:
|
||||||
|
words = line.split(' ')
|
||||||
|
word_widths = [d.textbbox((0, 0), word, font)[2] - d.textbbox((0, 0), word, font)[0] for word in words]
|
||||||
|
total_width = sum(word_widths) + (WORD_SPACING * (len(words) - 1))
|
||||||
|
x = (image_width - total_width) // 2 + SIDE_SPACING
|
||||||
|
for i, word in enumerate(words):
|
||||||
|
d.text((x, y), word, fill='black', font=font)
|
||||||
|
x += word_widths[i] + WORD_SPACING
|
||||||
|
y += line_height + line_spacing
|
||||||
|
|
||||||
|
img.save(filename)
|
||||||
|
|
||||||
|
print(f"PNG file created: {filename}")
|
||||||
|
|
||||||
|
if not debug:
|
||||||
|
os.system(
|
||||||
|
f'sudo brother_ql -b pyusb --model QL-570 -p usb://0x04f9:0x2028/000M6Z401370 --debug print -l 62 {filename}'
|
||||||
|
)
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
if len(sys.argv) < 2:
|
||||||
|
print("Usage: ./text_to_image.py <text_string> [debug]")
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
text = sys.argv[1].replace('\\n', '\n') # Add this line
|
||||||
|
debug = sys.argv[2] == 'debug' if len(sys.argv) > 2 else False
|
||||||
|
|
||||||
|
main(text, debug)
|
Loading…
Reference in New Issue
Block a user