AI Art

Creating cards for board game with ImageMagick and Python


Introduction

Why is it hard to create cards manually (one-by-one) and what can be the solution for this?

In board game design there are some time consuming processes like the creation of the cards. Did you now that this process can be automated? If you have a table or CSV file with the cards data (eg. Title, serial number, neccessary icons, images) and some basic images, then ImageMagick and Python can help you to create the cards. Imagine if you have 100 or more cards with different text on it and you decide to change the font or the background color. Instead of doing this manually for all 100 cards you can simply edit and run a Python script to update your cards.

In this article we will use the powerful and free ImageMagick tool which has a lot of image editing functions. Just check this site for examples, but avoid to deep dive into the documentation at this moment.

First, we write a Python script with the help of chatGPT.

Then we run the script and check the result.

Finally I give you a brief explanation of the most important parameters to understand which ones you need to edit to reach the expected result.

I will guide you through the whole process step-by-step.

It is good if you have some basic programming experience, but it is not a requirement to follow this tutorial.

If you are not familiar with programming or scripting or you just search for a more user friendly method, then jump to the end of this guide where I give you alternate ways to create the cards.

Tools we will use

  • ImageMagick,
  • Python,
  • chatGPT,
  • Notepad++ (or other IDE)
  • Google sheets or a CSV file

Steps before building and running the script

Installing Python

Go to python.org and download the latest version. Follow the steps of the installation wizard. Before selecting Install Now turn on “Add python.exe to PATH”.
This option gives you the ability to run Python scripts in any folder on your computer.

Make sure to check “Add python.exe to PATH”

Installing ImageMagick

Go to the ImageMagick website and select the appropriate version of the software.
I use Windows, so I downloaded and installed the Windows version.

Make sure to check the “Add application directory to your system path” option

Installing a text editor, like Notepad++

I recommend to use Notepad++, because it has many useful features, like syntax highlighting. Go to the Notepad++ download page and install it.

Remark: You can use any other text editor or IDE. The simplest text editor in Windows is Notepad, but it don’t have the syntax highlighting feature. Another popular and powerful IDE (Integrated Development Environment) is Visual Studio Code (shortly: vscode).

Creating the project folder

Use any file management tool (or command line) to create a project folder with any name you like. I created the create_cards folder for this example project.

Create a subfolder with the name images in the project folder. We will put our basic images into this folder.

Create the icons subfolder in the project folder and place the text bubble icon into this folder.

After the project folder and the cards subfolder are created move on to the next step.

This is the folder structure after all necessary folders are created:

Remark: The output folder will be created by the Python script.

Create or download the starting images

We need to put the starting card images into the cards folder and the message.png icon into the icons folder.

You can download them in one .zip file or one-by-one below.

message64.png:

Generating the first script

I use chatGPT to generate the Python code.

This is the prompt to generate the script (feel free to use other prompt to customize the script for your current project):

Help creating a Python script which uses ImageMagick to create cards for a fantasy themed card game. The card with is 45mm and the height is 68mm. The resolution is 150dpi. Use a CSV file as a data source for the cards. The CSV file contains the title, serial number, icon and base image. Place the title in the upper center part of the card in yellowish gold color on darkgreen background. Place the serial number in the upper left corner with black text and use an orange circle with black border as background. If the third column (icon) in the CSV file is True, then place the message64.png icon from the icons folder into the lower left corner on the card. Place the base image in the center of the card. Use darkblue background for the card. The base images are in the images folder. Save the cards into the cards_output folder. Be aware of how ImageMagick works: “Image Composition is the process of merging two (and only two) images in a variety of ways.”

So my prompt contains the following parameters:

  • Using a CSV file
  • Card size in millimeters
  • Print resolution in DPI (I use 150dpi for faster process and testing)
  • Using some images without any text and number (center align)
  • Card title (top align)
  • Card serial number in an orange circle
  • Message icon – if needed on a specific card

Tip: Be as concrete as you can when you formulate your prompt. Then the result will we more close to your wishes.

Script and CSV file what I got

Here you can see the script (double click on the code to select all):

import csv
import os
import subprocess

# Constants
MM_TO_INCH = 1 / 25.4
DPI = 150
CARD_WIDTH_MM = 45
CARD_HEIGHT_MM = 68

CARD_WIDTH_PX = int(CARD_WIDTH_MM * MM_TO_INCH * DPI)
CARD_HEIGHT_PX = int(CARD_HEIGHT_MM * MM_TO_INCH * DPI)

TITLE_HEIGHT = 60
TITLE_BG_COLOR = "darkgreen"
TITLE_TEXT_COLOR = "#FFD700"  # Yellowish gold
SERIAL_CIRCLE_COLOR = "orange"
SERIAL_BORDER_COLOR = "black"
SERIAL_TEXT_COLOR = "black"
ICON_PATH = "icons/message64.png"
ICON_SIZE = 64

def create_card(title, serial, icon, base_image_name, output_dir):
    base_image_path = os.path.join("images", base_image_name)
    output_path = os.path.join(output_dir, f"{serial}.png")

    draw_commands = []

    # Background
    draw_commands += [
        "canvas:darkblue",
        "-size", f"{CARD_WIDTH_PX}x{CARD_HEIGHT_PX}"
    ]

    # Start with a blank background
    command = ["magick", "convert"] + draw_commands

    # Add title background
    command += [
        "-fill", TITLE_BG_COLOR,
        "-draw", f"rectangle 0,0 {CARD_WIDTH_PX},{TITLE_HEIGHT}"
    ]

    # Title text (center top)
    command += [
        "-gravity", "North",
        "-fill", TITLE_TEXT_COLOR,
        "-font", "Arial-Bold",
        "-pointsize", "24",
        "-annotate", f"+0+10", title
    ]

    # Serial number circle (top-left)
    command += [
        "-fill", SERIAL_CIRCLE_COLOR,
        "-stroke", SERIAL_BORDER_COLOR,
        "-strokewidth", "2",
        "-draw", f"circle 30,30 30,0",
        "-gravity", "NorthWest",
        "-fill", SERIAL_TEXT_COLOR,
        "-font", "Arial",
        "-pointsize", "20",
        "-annotate", "+12+18", serial
    ]

    # Place base image in center
    command += [
        "(", base_image_path, "-resize", f"{CARD_WIDTH_PX-40}x{CARD_HEIGHT_PX-80}" , ")",
        "-gravity", "Center",
        "-geometry", "+0+20",
        "-composite"
    ]

    # Optional icon in lower-left
    if icon.strip().lower() == "true":
        command += [
            "(", ICON_PATH, "-resize", f"{ICON_SIZE}x{ICON_SIZE}", ")",
            "-gravity", "SouthWest",
            "-geometry", "+10+10",
            "-composite"
        ]

    # Output file
    command.append(output_path)

    subprocess.run(command)

def main():
    input_csv = "cards.csv"
    output_dir = "cards_output"
    os.makedirs(output_dir, exist_ok=True)

    with open(input_csv, newline='', encoding='utf-8') as csvfile:
        reader = csv.DictReader(csvfile)
        for row in reader:
            create_card(
                title=row["title"],
                serial=row["serial"],
                icon=row["icon"],
                base_image_name=row["base_image"],
                output_dir=output_dir
            )

if __name__ == "__main__":
    main()


Here is the csv file:

title,serial,icon,base_image
Spartan Soldier,01,True,spartan.png
Titan Warrior,02,False,titan.png
Elf Wizard,03,True,elf.png
Dark Goblin,04,False,goblin.png

Saving and running the script

chatGPT generated the Python script and a sample .csv file (see above).

Create a new Python file in your project folder, copy-paste the script and save it.
Remark: you can create a new file in Notepad++, paste the Python script and save as create_cards.py file.

Create a new CSV file and copy-paste the sample CSV file content from chatGPT or the code above. Save the file as cards.csv.

Run the script simply by double clicking on the filename.

If there are no errors, then the script runs and saves the card images into the cards_output folder. Check the folder for the results.

If there are errors in the Python script, then you should fix them to run the image export. See the Troubleshooting chapter to learn how to fix errors.

Tip: if you would like to see what Python writes on the screen, then do one of the following:

  1. run the script in command line. To do this open the command line by hitting the Windows button and type cmd, then hit ENTER. Navigate to the folder of the script (use cd foldername) and type the Python program name to run it.
  2. Insert the following line of code after the last line in the script in a new line and save the file:
    input(“Press ENTER to exit the program!”)

Editing the script

Right click on the .py file and select “Edit with NotePad++”. Be sure to save the file after editing.

Troubleshooting the script

Python prints error messages on the screen if the script contains errors. I help you fix these errors in this chapter.

“No such file or directory” error

magick: unable to open image ‘imagesspartan.png’: No such file or directory @ error/blob.c/OpenBlob/3596.

Solution:

  • copy the images to the correct folder
  • rename the images if the names are incorrect

Fine-tuning the results

Fixing object size, transparency settings and alignment

I made several fixing steps. You can download the final Python script from this link.

These are the thumbnails of the final images:

Changing text color

I checked the exported images and I see, that the text is too bright so I change the code:

Different aspect ratio

If you would like to create 1:1 aspect ratio images, then simply write the same number for width and height (row 8 and 9 in the Python script, CARD_WIDTH_MM and CARD_HEIGHT_MM).

Using Google fonts

You can easily change the font by replacing the approriate line:

I selected the Fancy Feeling on fonts.google.com and browsed through the fonts. My final decision was the Birthstone font.

Always read the license of the fonts to learn about the usage of them.

Creating exact number of some type of cards

Sometimes we need to create almost the same cards but with different text, icons and numbers.

Imagine that we would like to create a deck of 30 cards. 10 cards with a dragon, 10 cards with a knight, 5 cards with dwarfs, 5 cards with a sword.

Then instead of using different images for every card, we shoud include another column in the table or in the CSV file, which indicates which image we need on which card.

Prepare the cards for print

Now we have separate cards with nice text and icons. The next step is to print them. Use the following script to align more then one card on a page with. I use A4 paper size, but you can use any other standard. A4 paper dimensions: 210x297mm.

Alternative ways to create cards for board games

If you don’t like scripting and you would like to do this job with a more user friendly way, than you can use one of this tools:

The second one is very user friendly, you see the end result immediately and it can use CSV files. The free version can be enough for most of the use cases.

The list is not complete and I may change it later.

Final words

I hope you enjoyed this guide and found it useful. Happy card designing! If you have any questions feel free to ask them in the chat below!

Thanks for reading this long article!



Related Articles

Leave a Reply

Your email address will not be published. Required fields are marked *

Back to top button