Skip to main content

No project description provided

Project description

Poster Generator

A lightweight flexible Python library for building and rendering graphics with support for layers, groups, and YAML-based templates.

Python Version License

Features

โ€ข	๐Ÿงฑ Layering system for Z-order control and basic blend settings leveraging [Pillow](https://python-pillow.org/)

โ€ข	๐Ÿ—‚๏ธ Optional groups for quick categorization or batch selection

โ€ข	๐Ÿ“„ YAML templates with variable substitution for reusable layouts

โ€ข	๐ŸŽฏ Anchors & relative positioning for layout-style placement

โ€ข	๐Ÿ”Œ Extensible, format-agnostic registry for custom elements and operations

โ€ข	๐Ÿ› ๏ธ Function-driven operations (e.g., hue shifting, scaling, transforms)

โ€ข	๐Ÿ“ฃ Designed for automated poster and social media generation

โธป

Installation

Using Poetry (recommended)

poetry add poster-generator

Using pip

pip install poster-generator

From source

git clone https://github.com/corgi-in-tights/poster-generator.git
cd poster-generator
poetry install

Quick Start

Programmatic Usage

Create a simple poster with text and image elements:

from pathlib import Path
from poster_generator import Canvas, TextElement, ImageElement
from poster_generator.operations.image import apply_hue_shift

# Create a canvas
canvas = Canvas(width=1080, height=1350, background="#c75d5d")

# Add an image with hue shift
background = ImageElement(
    (0, 0),
    image_path="path/to/image.png",
    width=1080,
    height=1350,
)
background.apply_operation(lambda img: apply_hue_shift(img, 30))
canvas.add_element("background", background)

# Add text
text = TextElement(
    (50, 50),
    text="Hello, Poster!",
    font_size=200,
    color="#333333",
)
canvas.add_element("title", text)

# Render and save
image = canvas.render()
image.save("output.png")

YAML Template Usage

Define your poster in a YAML template:

---
schema: "1.0"
settings:
  width: 1080
  height: 1350
  background_color: "#f295df"

anchors:
  top_left:
    x: 50
    y: 50

layers:
  background:
    settings:
      opacity: 1.0
    elements:
      bg_image:
        type: image
        position: [0, 0]
        operations:
          apply_hue_shift:
            degrees: --${hue_shift}--
        values:
          image_path: --${background_image}--
          width: 1080
          height: 1350
    
  text:
    elements:
      title:
        type: text
        rel_position:
          source: anchor
          id: top_left
        values:
          text: --${title_text}--
          font_size: 64
          color: "#FFFFFF"

      subtitle:
        type: text
        rel_position:
          source: element
          id: title
          offset:
            x: 0
            y: 50
        values:
          text: My subtitle :)
          font_size: 30
          color: "#FFFFFF"

Load and render the template:

from poster_generator.loaders import YamlLoader

loader = YamlLoader()
canvas = loader.build_canvas(
    "template.yml",
    variables={
        "hue_shift": 45,
        "title_text": "My Poster",
        "background_image": "background.png",
    }
)

image = canvas.render()
image.save("output.png")

Core Concepts

Canvas

The Canvas is the main container for your poster. It manages elements, layers, and rendering.

canvas = Canvas(width=1080, height=1350, background="#ffffff")

Elements

Elements are the building blocks of your poster:

  • TextElement: Renders text with custom styling
  • ImageElement: Renders images with transformation support
# Text element
text = TextElement(
    position=(100, 100),
    text="Hello World",
    font_size=48,
    color="#000000"
)

# Image element
image = ImageElement(
    position=(0, 0),
    image_path="image.png",
    width=500,
    height=500
)

Layers

Layers help organize elements and control rendering order:

canvas.add_element("bg", background, layer="background")
canvas.add_element("title", text, layer="foreground")

Groups

Groups allow you to manage related elements:

canvas.add_element("title", text, groups=["headers", "top-section"])
canvas.add_element("subtitle", subtitle, groups=["headers", "top-section"])

# Query elements by group
headers = canvas.get_elements(groups="headers")

Operations

Apply transformations to elements:

from poster_generator.operations.image import apply_hue_shift, set_hue_from_hex

# Hue shift
element.apply_operation(lambda img: apply_hue_shift(img, degrees=45))

# Set hue from color
element.apply_operation(lambda img: set_hue_from_hex(img, "#FF5733"))

Advanced Usage

Custom Element Types

Register your own element types using the factory pattern:

from poster_generator.elements import DrawableElement, register_element_type

class CustomElement(DrawableElement):
    def __init__(self, position, custom_param=None):
        super().__init__(position)
        self.custom_param = custom_param
    
    def draw(self, draw, image, blend_settings: dict):
        # Your drawing logic
        pass
    
    def is_ready(self):
        return True
    
    def overlaps_region(self, x1, y1, x2, y2):
        return False
    
    def apply_operation(self, operation):
        pass

# Register the custom element
register_element_type("custom", CustomElement)

Element Queries

Query elements by identifier, group, or layer:

# Get specific elements
elements = canvas.get_elements(identifiers=["title", "subtitle"])

# Get by group
headers = canvas.get_elements(groups="headers")

# Get by layer
bg_elements = canvas.get_elements(layers="background")

# Combine filters (require all)
specific = canvas.get_elements(
    groups="headers",
    layers="foreground",
    require_all=True
)

YAML Variable Substitution

Use --${variable_name}-- syntax in YAML templates:

values:
  text: --${title}--
  font_size: --${size}--
  color: --${color}--
canvas = loader.build_canvas(
    "template.yml",
    variables={
        "title": "My Title",
        "size": 48,
        "color": "#FF0000"
    }
)

Relative Positioning

Position elements relative to anchors or other elements:

# Relative to anchor
rel_position:
  source: anchor
  id: top_left
  offset:
    x: 20
    y: 30

# Relative to another element
rel_position:
  source: element
  id: title
  offset:
    x: 0
    y: 50

API Reference

Canvas

  • Canvas(width, height, background) - Create a new canvas
  • add_element(identifier, element, groups=None, layer="default") - Add an element
  • remove_element(identifier) - Remove an element
  • get_elements(identifiers=None, groups=None, layers=None, require_all=False) - Query elements
  • clear_layer(layer) - Clear all elements from a layer
  • clear_group(group) - Clear all elements from a group
  • render(global_op=None) - Render the canvas to an image
  • from_dict(data) - Create canvas from dictionary

TextElement

  • TextElement(position, text=None, font_path=None, font_size=20, color="#000") - Create text element
  • draw(draw, image, position=None) - Draw the text
  • is_ready() - Check if ready to render

ImageElement

  • ImageElement(position, image_path=None, width=None, height=None) - Create image element
  • load_image(image_path) - Load an image file
  • apply_hue_shift(degrees) - Shift image hue
  • set_hue_from_hex(hex_color) - Set hue from color
  • apply_operation(operation) - Apply transformation
  • draw(draw, canvas_image, position=None) - Draw the image
  • is_ready() - Check if ready to render

YamlLoader

  • YamlLoader() - Create YAML loader
  • build_canvas(source, variables=None) - Build canvas from YAML file or dict

Examples

Check out the examples/ directory for more complete examples:

  • examples/basic.py - Programmatic poster creation
  • examples/yml.py - YAML template loading
  • examples/templates/my_template.yml - Example YAML template

Requirements

  • Python >= 3.13
  • Pillow >= 12.0.0
  • PyYAML >= 6.0.3

Development

Setup

# Clone the repository
git clone https://github.com/corgi-in-tights/poster-generator.git
cd poster-generator

# Install dependencies
poetry install

# Run examples
poetry run python examples/basic.py
poetry run python examples/yml.py

Project Structure

poster-generator/
โ”œโ”€โ”€ poster_generator/
โ”‚   โ”œโ”€โ”€ __init__.py
โ”‚   โ”œโ”€โ”€ canvas.py              # Canvas class
โ”‚   โ”œโ”€โ”€ settings.py            # Library settings
โ”‚   โ”œโ”€โ”€ elements/              # Element implementations
โ”‚   โ”‚   โ”œโ”€โ”€ drawable.py        # Base element class
โ”‚   โ”‚   โ”œโ”€โ”€ text.py            # Text element
โ”‚   โ”‚   โ”œโ”€โ”€ image.py           # Image element
โ”‚   โ”‚   โ””โ”€โ”€ factory.py         # Element factory
โ”‚   โ”œโ”€โ”€ loaders/               # Template loaders
โ”‚   โ”‚   โ”œโ”€โ”€ base.py            # Base loader
โ”‚   โ”‚   โ””โ”€โ”€ yaml_loader.py     # YAML loader
โ”‚   โ””โ”€โ”€ operations/            # Image operations
โ”‚       โ”œโ”€โ”€ image.py           # Image transformations
โ”‚       โ””โ”€โ”€ factory.py         # Operation factory
โ”œโ”€โ”€ examples/                  # Example scripts
โ”œโ”€โ”€ tests/                     # Test suite
โ””โ”€โ”€ README.md

Contributing

Contributions are welcome! Please feel free to submit a Pull Request. I am open to significant design changes if they match the project's intention.

License

This project is licensed under the MIT License - see the LICENSE file for details.

Issues

I cannot guarantee this project will be actively maintained since there really isn't much to add from my end. The current end product fulfills my rather primitive needs -- however, if any critical bugs come up, please open a GitHub issue.

If there are architectural issues (i.e. inflexible code), then please feel free to open an issue, but for additional features, a PR would be much preferred.

Acknowledgments

  • Built with Pillow for image processing
  • Uses PyYAML for template parsing (by default)
  • This project and README was partially built with the help of Claude, though all architectural decisions are fully my own.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

poster_generator-1.0.0.tar.gz (365.4 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

poster_generator-1.0.0-py3-none-any.whl (366.8 kB view details)

Uploaded Python 3

File details

Details for the file poster_generator-1.0.0.tar.gz.

File metadata

  • Download URL: poster_generator-1.0.0.tar.gz
  • Upload date:
  • Size: 365.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.5

File hashes

Hashes for poster_generator-1.0.0.tar.gz
Algorithm Hash digest
SHA256 279c89d609e6400dc2573580b4af3adaa063e32e8e4fdb0572aa589fce628d94
MD5 f27b6bae549c7377499b9fe666ef50a4
BLAKE2b-256 ca5d18212d6702582d063e24a94db5cf1f2dfba7d1c88e5110b17e0a7b18504b

See more details on using hashes here.

File details

Details for the file poster_generator-1.0.0-py3-none-any.whl.

File metadata

File hashes

Hashes for poster_generator-1.0.0-py3-none-any.whl
Algorithm Hash digest
SHA256 30dd7df2fabfce769116900d5b4f560e829528e3c4ec7423444c078c43601d21
MD5 fa6ca5e365ffbf3ed56286be1d4ace29
BLAKE2b-256 d58d25ded242641756605aa2c9d66dc981879c78cbda0a53a41572b773494cf4

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page