Our wedding is coming up, and I’m running out of time. It’s a bit hectic, trying to plan two events in two different places hundred kilometers apart.
I was planning to give my friends invites but was running out of time fast, Had to send the invites digitally; via WhatsApp to be precise.
I can’t just send an blank invite, that’s too impersonal! Have to at least address it to the invitee.
Automating it!
As you can see my card is fairly simple, just need to tack on some text in the middle and it works. I decided to ask ChatGPT to make me a script for that. With the following requirements,
- Take an input text file with a guest name in each new line
- Open a PNG of my wedding card
- Iterate and add horizontally centered name with a predefined vertical offset
It failed at it, It misunderstood my need at first (probably my fault) but most importantly it wasn’t aware of deprecated API’s of Pillow (the library of choice for image processing in Python)
After hacking on the script for a couple of minutes, I was able to get it to working.
from PIL import Image, ImageDraw, ImageFont
FONT_SIZE = 60
FONT_TTF = "DancingScript-Regular.ttf"
def add_names_to_invitation(suffix, invitation_path, y_offset, names_file_path, output_folder):
# Open the wedding invitation image
invitation_image = Image.open(invitation_path)
# Define coordinates for the center alignment
width, height = invitation_image.size
center_x = width // 2
# Load a font for the names
font = ImageFont.truetype(FONT_TTF, FONT_SIZE)
# Open the file containing names
with open(names_file_path, 'r') as file:
for idx, name in enumerate(file):
# Remove newline characters
name = name.strip()
# Make copy of the image
cur = invitation_image.copy()
draw = ImageDraw.Draw(cur)
# Calculate position for each name
text_width = draw.textlength(name, font=font)
name_x = center_x - text_width // 2
name_y = y_offset - FONT_SIZE // 2
# Add the name to the invitation
draw.text((name_x, name_y), name, fill="black", font=font)
# Save the invitation with the name
output_path = f"{output_folder}/invitation_{name}_{suffix}.png"
cur.save(output_path)
print(f"Writing {output_path}")
if __name__ == "__main__":
names_file_path = "guest_names.txt"
output_folder = "output"
add_names_to_invitation("cmb", "Colombo Card.png", 1160, names_file_path, output_folder)
add_names_to_invitation("kdy", "Kandy Card.png", 1095, names_file_path, output_folder)
I threw in a custom script font which is attributed1 as public domain. I had two different cards, for which I just made the method functional with parameters for the y axis offset and a file name suffix.
Why not do it manually?
I get so frustrated at times doing things manually, especially in the realm of computing as the task of the computer is to reduce repetition, so I wouldn’t have. Also two cards per person, would have made it a fun task2.
But thanks to LLM giving me a good enough starting point, was able to get it done in a short amount of time, the code is yucky, but it serves it’s purpose.
It didn’t turn out to be like the Automation XKCD, which I’m happy about. My fiancĂ©e also made use of it to send some digital cards.