Skip to content
weirdappsPublic

About

Pixel-perfect iPhone mockup generator using flood-fill masking

Topics

Resources

Security policy

Stars

0 stars

Watchers

0 watching

Forks

Repository files navigation

iPhone Mockup Generator

Pixel-perfect iPhone mockups from any screenshot, in one command. The screenshot is composited inside a bundled Apple device frame PNG using a flood-fill masking algorithm, so content stays strictly inside the curved screen area with no bleeding through the rounded corners.

CI Quality Gate Status Python License

What it does

You give it a clean screenshot (PNG or JPG, any resolution). It gives you back a full-resolution PNG with a transparent background, showing that screenshot placed inside a real iPhone frame. Ready for presentations, App Store previews, marketing sites, or design hand-offs.

Six device frames ship inside the package, no runtime download or external asset directory required.

Device frames

iPhone 16 Pro Max Black Titanium
16_pro_max_black
(default)
iPhone 16 Pro Max Natural Titanium
16_pro_max_natural
iPhone 16 Pro Max White Titanium
16_pro_max_white
iPhone 16 Pro Max Desert Titanium
16_pro_max_desert
iPhone 16 Pro Black Titanium
16_pro_black
iPhone 16 Pro Natural Titanium
16_pro_natural

Pro Max frames output at 1520 x 3068 px. Pro frames output at 1406 x 2822 px.

How the masking works

A device frame PNG has two transparent regions: the outer rounded corners (outside the phone body) and the inner screen area. A naive alpha check would let the screenshot bleed through both. Instead, _flood_fill_screen_mask in src/mockups/core.py seeds a BFS from the center of the frame and expands only through the connected inner transparent region, producing a pixel-accurate screen mask that respects every curve. The screenshot is resized to the frame's content rectangle with LANCZOS resampling, masked, then alpha-composited under the frame overlay.

Installation

For everyday use, install the CLI in an isolated environment with pipx:

pipx install git+https://github.com/weirdapps/mockups.git

(Install pipx first if needed: brew install pipx.)

For use as a library or for development:

pip install git+https://github.com/weirdapps/mockups.git

Requires Python 3.9 or newer. Dependencies (Pillow and NumPy) are pulled in automatically.

Usage

Command line

# Default frame (iPhone 16 Pro Max Black Titanium),
# writes screenshot_mockup.png next to the input.
mockup screenshot.png

# Explicit output path.
mockup screenshot.png out.png

# Pick a specific frame.
mockup screenshot.png --frame 16_pro_black

# List every available frame.
mockup --list-frames

# Point at a custom directory of frame PNGs
# (must contain the filenames listed by --list-frames).
mockup screenshot.png --frames-dir /path/to/frames

Full flag reference:

Flag Description
screenshot (positional) Path to the input screenshot (PNG or JPG).
output (positional, optional) Output path. Defaults to <screenshot-stem>_mockup.png in the same directory.
--frame, -f Frame key to use. Choices come from the six bundled frames. Default: 16_pro_max_black.
--list-frames Print the available frame keys and their PNG filenames, then exit.
--frames-dir Override the bundled frames directory (advanced).

Python API

from mockups import create_mockup, FRAMES, DEFAULT_FRAME

output = create_mockup(
    screenshot_path="screenshot.png",
    output_path="mockup.png",  # optional
    frame_key="16_pro_max_black",  # optional, defaults to DEFAULT_FRAME
    frames_dir=None,  # optional override
)
print(f"Saved: {output}")

# Enumerate frames programmatically.
for key, cfg in FRAMES.items():
    print(key, cfg["path"])

create_mockup raises ValueError for an unknown frame_key and FileNotFoundError for a missing screenshot or missing frame PNG.

Input and output

Details
Input formats PNG, JPG (any resolution, resized with LANCZOS to fit the frame's content rectangle).
Best input Clean screenshots with no existing device chrome or frame artifacts.
Output format PNG with a transparent background (RGBA).
Default output name <input-stem>_mockup.png, written next to the input.
Pro Max output size 1520 x 3068 px.
Pro output size 1406 x 2822 px.

Architecture

src/mockups/
  __init__.py          Public API: create_mockup, FRAMES, DEFAULT_FRAME.
  core.py              Flood-fill masking, frame registry, image composition.
  cli.py               argparse CLI entry point (mockup).
  frames/              Six bundled iPhone 16 Pro / Pro Max PNGs.
tests/
  test_mockup.py       CLI, frame registry, and end-to-end composition tests.

Add a new frame by dropping its PNG into src/mockups/frames/ and adding an entry to the FRAMES dict in core.py with the four content-rectangle coordinates (content_left, content_top, content_right, content_bottom).

Development

# HTTPS (no SSH key required):
git clone https://github.com/weirdapps/mockups.git
# or, with SSH:
git clone git@github.com:weirdapps/mockups.git
cd mockups
python3 -m venv .venv && source .venv/bin/activate
pip install -e .
pip install pytest
pytest

The project uses Ruff for linting and formatting, and pre-commit hooks that also run mypy, gitleaks, yamllint, and markdownlint. CI (.github/workflows/ci.yml) runs ruff check and ruff format --check, then pytest, on every push and PR to master.

Ruff is pinned to an exact version in CI (pip install ruff==0.16.1) and must be kept in sync with the ruff-pre-commit rev in .pre-commit-config.yaml. Bump both together. Note that ruff format also formats Python code blocks inside Markdown, so the snippets in this README are checked by CI too.

Install the hooks locally with:

pip install pre-commit && pre-commit install

License

MIT. Copyright (c) 2026 Dimitrios Plessas.

Acknowledgments

Device frame images are based on Apple's publicly available product imagery. iPhone is a trademark of Apple Inc., registered in the U.S. and other countries. This project is not affiliated with or endorsed by Apple.

Built with Pillow and NumPy.

About

Pixel-perfect iPhone mockup generator using flood-fill masking

Topics

Resources

Security policy

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages