diff --git a/README.md b/README.md index 655f22c..18c2d2f 100644 --- a/README.md +++ b/README.md @@ -9,10 +9,14 @@ How to use: shirtfile: ``` +# define variants to be generated +variants: _black:0:0:0 _white:255:255:255 _red:255:0:0 + +# declare lines m:b:fill FIRST m:r:fill second line r:r:400 third line ``` -output: -![three lines of text, the first one is really big and says "first", the second line is smaller and says "second line" a third, even smaller line says "third line"](example.png) \ No newline at end of file +output (red variant): +![three lines of text, the first one is really big and says "first", the second line is smaller and says "second line" a third, even smaller line says "third line"](example_red.png) \ No newline at end of file diff --git a/example.png b/example.png deleted file mode 100644 index 83b2f8d..0000000 Binary files a/example.png and /dev/null differ diff --git a/example.shirt b/example.shirt index 5dcc84d..f739f95 100644 --- a/example.shirt +++ b/example.shirt @@ -1,3 +1,7 @@ +# define variants to be generated +variants: _black:0:0:0 _white:255:255:255 _red:255:0:0 + +# declare lines m:b:fill FIRST m:r:fill second line r:r:400 third line \ No newline at end of file diff --git a/example_red.png b/example_red.png new file mode 100644 index 0000000..94ef1e3 Binary files /dev/null and b/example_red.png differ diff --git a/gen.py b/gen.py index 68546c8..282f345 100644 --- a/gen.py +++ b/gen.py @@ -7,6 +7,9 @@ fonts = { "b": "fonts/F25_Bank_Printer_Bold.ttf", } +# image size is defined as 5000 x 5000 pixels +size = (5000, 5000) + if len(sys.argv) == 1: print("please specify a path to a shirtfile") exit(1) @@ -14,10 +17,19 @@ if len(sys.argv) == 1: # parse shirtfile into list of tuples # # shirtfile syntax: -# a shirtfile is a plain-text file made up of lines in the following format +# a shirtfile is a plain-text file made up of the following compontents +# +# different text color variants are defined on a line as follows +# variants: [{file_suffix}:{r}:{g}:{b}] ... +# where: +# - file_suffix is the suffix to be added to a file of this variant, can be left empty +# - r, g and b are the red, green and blue color components respecively (0-255) +# if no variants are specified white text will be output to a file with no suffix +# +# lines of text are defined as lines in the following format # {alignment}:{font}:{size} {text} # where: -# - alignment can be: +# - alignment can be: # * 'm' for centered text # * 'l' for left aligned text # * 'r' for right aligned text @@ -27,8 +39,10 @@ if len(sys.argv) == 1: # - size is either 'fill' to automatically calculate a font size to fill the width of the canvas # or a font size in pixels # - text is your desired line of text (with no line breaks) +# # the shirtfile parser treats lines starting with # as comments and ignores empty lines # +variants = [] texts = [] with open(sys.argv[1], "r") as f: lines = f.readlines() @@ -38,11 +52,25 @@ with open(sys.argv[1], "r") as f: if line.startswith("#") or len(line.strip()) == 0: continue + # parse variants + if line.startswith("variants:"): + if len(variants) > 0: + print("variants block can only appear once") + exit(1) + parts = line.strip().removeprefix("variants: ").split(" ") + for variant in parts: + subparts = variant.split(":") + variants.append( + (subparts[0], (int(subparts[1]), int(subparts[2]), int(subparts[3])))) + continue + + # parse lines parts = line.strip().split(" ", 1) texts.append(tuple(parts[0].split(":")) + (parts[1],)) -# create transparent 5000x5000 image -im = Image.new("RGBA", (5000, 5000), (0, 0, 0, 0)) +# default to white output with no filename suffix +if len(variants) == 0: + variants.append(("", (255, 255, 255))) # quick maths # calculate appropriate text sizes and bounding box sizes for positioning later @@ -57,7 +85,7 @@ for text in texts: if text[2] == "fill": # dynamic font size calc is hell # reload font at increasing size until we fill out the whole canvas width - while bbox_size[0] < (im.size[0] - 5): + while bbox_size[0] < (size[0] - 5): font = ImageFont.truetype(font_path, font_size) bbox = font.getbbox(text[3], anchor=f"{text[0]}b") bbox_size = (bbox[2] - bbox[0], bbox[3] - bbox[1]) @@ -77,27 +105,34 @@ for text in texts: # account for padding total_height += (len(texts) - 1) * 20 -# draw the text -draw = ImageDraw.Draw(im) -y_offset = 0 -for text in p_texts: - # set x location dependent on alignment - loc_x = 0 - if text[0] == "m": - loc_x = (im.size[0]/2) - elif text[0] == "r": - loc_x = im.size[0] +p_variants = [] - # calculate y location based on total height of all text + current line height to - # center all text together in the center of the canvas - loc_y = (im.size[1]/2 + total_height / 2) + text[5][1] + y_offset +for variant in variants: + # create transparent image + im = Image.new("RGBA", size, (0, 0, 0, 0)) - draw.text((loc_x, loc_y), text[3], font=text[4], anchor=f"{text[0]}b") + # draw the text + draw = ImageDraw.Draw(im) + y_offset = 0 + for text in p_texts: + # set x location dependent on alignment + loc_x = 0 + if text[0] == "m": + loc_x = (im.size[0]/2) + elif text[0] == "r": + loc_x = im.size[0] - # add height of this line to offset - y_offset += text[5][1] + 20 + # calculate y location based on total height of all text + current line height to + # center all text together in the center of the canvas + loc_y = (im.size[1]/2 + total_height / 2) + text[5][1] + y_offset -# crop to content and save -im = im.crop(im.getbbox()) -filename = sys.argv[1].removesuffix(".shirt") -im.save(f"{filename}.png", 'PNG') + draw.text((loc_x, loc_y), text[3], font=text[4], + anchor=f"{text[0]}b", fill=variant[1]) + + # add height of this line to offset + y_offset += text[5][1] + 20 + + # crop to content and save + im = im.crop(im.getbbox()) + filename = sys.argv[1].removesuffix(".shirt") + im.save(f"{filename}{variant[0]}.png", 'PNG')