Render all the designs currently available into images showcasing them for the purpose of displaying it on the Factorio Mod portal.
108 lines
No EOL
3.2 KiB
Python
108 lines
No EOL
3.2 KiB
Python
from PIL import Image, ImageFont, ImageDraw
|
|
from designs import models
|
|
|
|
def make_image(output, items, header, render, text_width, col_width, cols, description=None, transpose=False, scale=1):
|
|
col_width += text_width
|
|
row_width = int(256 * scale)
|
|
header_height = 180
|
|
description_height = 100 if description else 0
|
|
footer_height = 80
|
|
rows = (len(items) + cols - 1) // cols
|
|
|
|
width = cols * col_width
|
|
height = header_height + description_height + rows * row_width + footer_height
|
|
|
|
font = ImageFont.truetype("FiraSans-Regular", 52)
|
|
output_im = Image.new("RGBA", (width, height))
|
|
ctx = ImageDraw.Draw(output_im)
|
|
def paste_im(model, variant, co):
|
|
im = Image.open(f"src/graphics/technology/{model}_{variant.replace('liquid', 'clear')}.png")
|
|
src = im.resize((int(256 * scale), int(256 * scale)), 1) if scale != 1 else im
|
|
output_im.paste(src, co)
|
|
im.close()
|
|
|
|
white = (255, 255, 255, 255)
|
|
def text_im(text, co):
|
|
ctx.text(co, text, font=font, fill=white, anchor="lm")
|
|
|
|
for i, item in enumerate(items):
|
|
if transpose:
|
|
col, row = i % cols, i // cols
|
|
else:
|
|
col, row = i // rows, i % rows
|
|
x, y = col * col_width, header_height + description_height + row * row_width
|
|
render(item, x, y, paste_im, text_im)
|
|
|
|
|
|
if description:
|
|
ctx.text((width / 2, header_height + description_height / 2 - 40), description, font=font, fill=white, anchor="mm")
|
|
h_font = ImageFont.truetype("FiraSans-Bold", 100)
|
|
ctx.text((width / 2, header_height / 2), header, font=h_font, fill=white, anchor="mm")
|
|
f_font = ImageFont.truetype("FiraSans-Regular", 40)
|
|
ctx.text((width - 10, height - 10), "Quality Glassware / by Hornwitser / CC BY-SA 4.0", font=f_font, fill=white, anchor="rd")
|
|
|
|
|
|
print(f"saving {output}")
|
|
output_im.save(output)
|
|
|
|
def render_model(model, x, y, paste_im, text_im):
|
|
name = model["name"]
|
|
print(f"pasting {name}")
|
|
paste_im(name, "empty", (x, y))
|
|
paste_im(name, "liquid_red", (x + 256, y))
|
|
text_im(name, (x + 512 + 10, y + 128))
|
|
|
|
make_image("images/models.png",
|
|
items = models.values(),
|
|
header = "Models",
|
|
render = render_model,
|
|
text_width = 400,
|
|
col_width = 2 * 256,
|
|
cols = 4,
|
|
)
|
|
|
|
def render_variant(variant, x, y, paste_im, text_im):
|
|
name = variant["name"]
|
|
model = variant["model"]
|
|
print(f"pasting {name}")
|
|
paste_im(model, name, (x, y))
|
|
text_im(name, (x + 256 + 10, y + 128))
|
|
|
|
make_image("images/variants.png",
|
|
items = models["sphere_hemi"]["variants"].values(),
|
|
header = "Variants",
|
|
render = render_variant,
|
|
text_width = 400,
|
|
col_width = 256,
|
|
cols = 2,
|
|
)
|
|
|
|
make_image("images/frozen.png",
|
|
items = list(v for v in models["cone_normal"]["variants"].values() if v["contents"] == "frozen"),
|
|
header = "Frozen Variants",
|
|
description = "Only the cone_normal model has frozen variants.",
|
|
render = render_variant,
|
|
text_width = 400,
|
|
col_width = 256,
|
|
cols = 2,
|
|
)
|
|
|
|
def render_design(variant, x, y, paste_im, text_im):
|
|
if not variant: return
|
|
name = variant["name"]
|
|
model = variant["model"]
|
|
print(f"pasting {name}")
|
|
paste_im(model, name, (x, y))
|
|
|
|
all_designs = [v for m in models.values() for v in m["variants"].values()]
|
|
all_designs.insert(12, None)
|
|
|
|
make_image("images/all-designs.png",
|
|
items = all_designs,
|
|
header = "All Designs",
|
|
render = render_design,
|
|
text_width = 0,
|
|
col_width = 128,
|
|
cols = len(models) + 1,
|
|
scale = 0.5,
|
|
) |