Итоговый код

import uuid
from dataclasses import dataclass
from typing import Optional

from PIL import Image, ImageDraw, ImageFont


@dataclass
class Point:
    x: Optional[int]
    y: int


@dataclass
class Meme:
    filename: str
    slots: list[Point]


MEMES = {
    'Coding cat': Meme(
        'img/coding_cat.jpg',
        [
            Point(None, 15),
            Point(None, 250)
        ]
    ),
    'Hackerman': Meme(
        'img/hackerman.jpg',
        [
            Point(None, 20)
        ]
    ),
}


def create_font(img, label, name, default_size):
    font = ImageFont.truetype(name, default_size)
    label_width = font.getlength(label)
    ratio = label_width / img.width
    max_ratio = 0.8

    if ratio > max_ratio:
        new_size = int(default_size / (1 + ratio - max_ratio))
        return ImageFont.truetype(name, new_size)

    return font


def calc_left_padding(img, label, font):
    label_width = font.getlength(label)
    return int((img.width - label_width) / 2)


def make_unique_filename(source):
    filename, _, extension = source.rpartition('.')
    return f'{filename}_{uuid.uuid4()}.{extension}'


def fill_meme(meme, labels):
    slots_count = len(meme.slots)
    labels_count = len(labels)
    if slots_count != labels_count:
        raise ValueError(
            'Неверное количество надписей: '
            f'ожидалось {slots_count}, '
            f'получено {labels_count}'
        )

    # Загружаем изображение
    with Image.open(meme.filename) as img:
        canvas = ImageDraw.Draw(img)

        for slot, label in zip(meme.slots, labels):
            label = label.upper()
            default_font_size = img.height // 6
            font = create_font(img, label, 'ariblk.ttf', default_font_size)

            x, y = slot.x, slot.y
            if x is None:
                x = calc_left_padding(img, label, font)
            canvas.text((x, y), label, font=font, fill='white')

        filename = make_unique_filename(meme.filename)
        img.save(filename)


fill_meme(MEMES['Coding cat'], ['Компилируем HTML', 'В CSS'])
fill_meme(MEMES['Coding cat'], ['2 минуты пишу код', '3 часа отлаживаю'])
fill_meme(MEMES['Hackerman'], ['from PIL import *'])
fill_meme(MEMES['Hackerman'], ['print("Hello, world")'])