Skip to content

Chuntttttt/Cards

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

76 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

Cards

Code Quality macOS build Ubuntu build Windows build Deploy WASM License: MIT

A Rust workspace for converting card images into printable PDFs with cutting guidelines. Available as a web app, GUI application, CLI tool, and library. Written using MIT-licensed printpdf for PDF generation.

Features

  • 🌐 Web App: Browser-based WASM version (no installation)
  • πŸ–₯️ Desktop GUI: Native cross-platform application
  • πŸ’» CLI Tool: Command-line interface for automation
  • πŸ“š Library: Embed in your own Rust projects
  • 🎴 Card layouts: Configurable grid sizes (1Γ—1 to 20Γ—20)
  • βœ‚οΈ Cutting guides: Automatic crosshairs and edge lines for precise cutting
  • πŸ”„ Double-sided printing: Back cards automatically aligned for flipping
  • πŸ–ΌοΈ Multiple formats: Supports PNG, JPG, and JPEG images
  • πŸ“„ Letter size: Generates standard 8.5Γ—11 inch PDFs

Installation

Web App

Try the web version (no installation required): https://chuntttttt.github.io/Cards/

Upload a ZIP file containing your cards and generate PDFs entirely in your browser!

CLI Tool

Download Pre-built Executables

Download the latest release for your platform from the Releases page. No dependencies required!

Build from Source

Requires Rust 1.70+ and Cargo:

# Clone the repository
git clone https://github.com/Chuntttttt/Cards.git
cd Cards

# Build CLI and GUI (native applications)
cargo build --release --workspace

# Build CLI only
cd cards-cli && cargo build --release

# Build GUI only
cd cards-gui && cargo build --release

# Build WASM webapp (requires wasm32 target and trunk)
rustup target add wasm32-unknown-unknown
cargo install trunk
cd cards-wasm && trunk build --release

# Executables will be at:
# - CLI: ./target/release/cards
# - GUI: ./target/release/cards-gui
# - WASM: ./cards-wasm/dist/ (HTML + WASM bundle)

Library

Add to your Cargo.toml:

[dependencies]
cards-core = { git = "https://github.com/Chuntttttt/Cards.git" }

Or use a local path:

[dependencies]
cards-core = { path = "../Cards/cards-core" }

Usage

CLI Tool

Cards turns a folder structure like this:

cards/
      front/
            card_01.png
            card_02.png
            ...
            card_50.png
      back/
            back_01.png
            back_02.png
            ...
            back_50.png

Into a PDF with cutting guidelines and interleaved front/back cards for double-sided printing.

The card images should be 2.5x3.5 (poker card ratio). You can set the number of rows/columns by passing the --sides argument (defaults to 3x3 on each page).

If there are more front cards than back cards, the last back card will be duplicated for the remaining unmatched front cards.

Command Line Options

cards --cards-path <PATH> [OPTIONS]

Options:
  -c, --cards-path <PATH>   Path to the folder containing card images (required)
  -o, --output <FILE>       Output PDF filename [default: cards.pdf]
  -s, --sides <N>           Grid size (e.g., 3 for 3x3) [default: 3]
  -v, --verbose             Show progress messages
  -h, --help                Print help

Example Invocations

# Generate 3x3 grid PDF
./target/release/cards --cards-path path/to/cards --output cards.pdf

# Generate 5x5 grid PDF with verbose output
./target/release/cards --cards-path path/to/cards --output cards.pdf --sides 5 --verbose

Library Usage

Generate PDF File

use cards_core::CardWriter;

fn main() -> Result<(), Box<dyn std::error::Error>> {
    let writer = CardWriter::new("path/to/cards".to_string(), 3);
    writer.create_pdf("output.pdf")?;
    println!("PDF created successfully!");
    Ok(())
}

Generate PDF as Bytes (for web services)

use cards_core::CardWriter;

fn generate_pdf_response(cards_path: String) -> Result<Vec<u8>, cards_core::CardsError> {
    let writer = CardWriter::new(cards_path, 3);
    let pdf_bytes = writer.generate_pdf_bytes()?;
    Ok(pdf_bytes)
}

With Logging

use cards_core::CardWriter;

fn main() -> Result<(), Box<dyn std::error::Error>> {
    // Configure logging (optional)
    env_logger::init();

    let writer = CardWriter::new("path/to/cards".to_string(), 3);
    writer.create_pdf("output.pdf")?;
    Ok(())
}

Error Handling

use cards_core::{CardWriter, CardsError};

fn create_cards() -> Result<(), CardsError> {
    let writer = CardWriter::new("path/to/cards".to_string(), 3);

    match writer.create_pdf("output.pdf") {
        Ok(_) => println!("Success!"),
        Err(CardsError::DirectoryNotFound(path)) => {
            eprintln!("Directory not found: {}", path);
        },
        Err(CardsError::ImageDecodeError(msg)) => {
            eprintln!("Failed to decode image: {}", msg);
        },
        Err(e) => eprintln!("Error: {}", e),
    }

    Ok(())
}

Example Outputs

3x3 example

5x5 example

About

Convert images of 2.5x3.5 game cards to letter-sized pdf sheets with guidelines for cutting with scissors once printed, primarily for print & play games.

Resources

License

Stars

Watchers

Forks

Contributors