{"id":49322060,"url":"https://github.com/hbmartin/imagemine","last_synced_at":"2026-04-26T18:02:45.667Z","repository":{"id":343083241,"uuid":"1176211633","full_name":"hbmartin/imagemine","owner":"hbmartin","description":"📸 → 🍌 → 🖼️ ... Re-imagine any photo into fantastical art. imagemine uses Claude to write a surrealist story about your photo, then generates a new image from that description using Gemini / Nano Banana.","archived":false,"fork":false,"pushed_at":"2026-03-21T18:19:43.000Z","size":951,"stargazers_count":2,"open_issues_count":0,"forks_count":1,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-03-22T04:04:15.822Z","etag":null,"topics":["anthropic-claude","claude","gemini","generative-ai","generative-art","image-generation","image-manipulation","image-processing","nano-banana","nanobanana","photos"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/hbmartin.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-03-08T19:09:18.000Z","updated_at":"2026-03-21T13:43:20.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/hbmartin/imagemine","commit_stats":null,"previous_names":["hbmartin/imagemine"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/hbmartin/imagemine","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hbmartin%2Fimagemine","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hbmartin%2Fimagemine/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hbmartin%2Fimagemine/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hbmartin%2Fimagemine/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/hbmartin","download_url":"https://codeload.github.com/hbmartin/imagemine/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hbmartin%2Fimagemine/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32307017,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-26T17:23:19.671Z","status":"ssl_error","status_checked_at":"2026-04-26T17:23:19.195Z","response_time":129,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["anthropic-claude","claude","gemini","generative-ai","generative-art","image-generation","image-manipulation","image-processing","nano-banana","nanobanana","photos"],"created_at":"2026-04-26T18:02:44.898Z","updated_at":"2026-04-26T18:02:45.661Z","avatar_url":"https://github.com/hbmartin.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# imagemine\n\n[![PyPI](https://img.shields.io/pypi/v/imagemine.svg)](https://pypi.org/project/imagemine/)\n[![Ruff](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/ruff/main/assets/badge/v2.json)](https://github.com/astral-sh/ruff)\n[![ty](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/ty/main/assets/badge/v0.json)](https://github.com/astral-sh/ty)\n[![CI](https://github.com/hbmartin/imagemine/actions/workflows/ci.yml/badge.svg)](https://github.com/hbmartin/imagemine/actions/workflows/ci.yml)\n[![codecov](https://codecov.io/gh/hbmartin/imagemine/graph/badge.svg?token=prrlAXa92n)](https://codecov.io/gh/hbmartin/imagemine)\n[![Ask DeepWiki](https://deepwiki.com/badge.svg)](https://deepwiki.com/hbmartin/imagemine)\n\n\nTransform any photo into something new. imagemine uses Claude to write a surrealist story about your photo, then generates a new image from that description using Gemini / Nano Banana.\n\n## Table of Contents\n\n- [How it works](#how-it-works)\n- [Requirements](#requirements)\n- [Quick Start](#quick-start)\n- [API keys](#api-keys)\n- [CLI flags](#cli-flags)\n- [Styles](#styles)\n- [Character Mappings](#character-mappings)\n- [Configuration](#configuration)\n- [Apple TV screensaver](#apple-tv-screensaver)\n- [Development](#development)\n- [Legal](#legal)\n\n## How it works\n\n1. Resize input image to max 1024px (preserving aspect ratio) and save to disk\n2. Send the resized image to Claude Sonnet via the Files API; generate a short surrealist story and image prompt\n3. Pick a random visual style from the built-in style library (or specify one with `--style`)\n4. Pass the story + style + resized image to Gemini to generate the re-imagined version\n5. Save all run metadata to a local SQLite database (`~/.imagemine.db`)\n\n## Requirements\n\n- Python 3.14+\n- An [Anthropic API key](https://console.anthropic.com/)\n- A [Google Gemini API key](https://aistudio.google.com/apikey)\n\n## Quick Start\n\n```sh\nuvx imagemine path/to/photo.jpg\n```\n\nThe generated image is saved to the current directory. The terminal UI shows each pipeline step with live spinners, elapsed timers, and a final summary panel.\n\n### Installing\n\nTo use imagemine without invoking uvx, permanently install it as:\n\n```sh\ncurl -LsSf uvx.sh/imagemine/install.sh | sh\nimagemine path/to/photo.jpg\n```\n\n## API keys\n\nKeys are resolved in this order on each run:\n\n1. **Database** — stored in `~/.imagemine.db` after first entry\n2. **Environment variables** — `ANTHROPIC_API_KEY`, `GEMINI_API_KEY`\n3. **Interactive prompt** — if neither is found, you are prompted (input is masked) and the value is saved to the database for future runs\n\nTo set keys via environment:\n\n```sh\nexport ANTHROPIC_API_KEY=sk-ant-...\nexport GEMINI_API_KEY=AI...\n```\n\nTo set or update keys directly in the config database:\n\n```sh\nimagemine --config\n```\n\n## CLI flags\n\n| Flag                  | Default    | Description                                              |\n| --------------------- | ---------- | -------------------------------------------------------- |\n| `image_path`          | —          | Path to input image (omit to use `--input-album`)        |\n| `--input-album`       | DB / env   | macOS Photos album to pick a random input image from     |\n| `--output-dir`        | `.`        | Directory to save the generated image                    |\n| `--desc-temp`         | DB / `1.0` | Sampling temperature for Claude description generation   |\n| `--img-temp`          | DB / `1.0` | Sampling temperature for Gemini image generation         |\n| `--story TEXT`        | —          | Background context prepended to the Claude prompt when generating the image description             |\n| `--style PROMPT`      | —          | Use PROMPT as the style instead of a randomly selected one from the database                        |\n| `--fresh`             | off        | Pick style randomly from the least-used styles (ignored when `--style` is given)                    |\n| `--choose-style`      | off        | Interactively pick style(s) from a numbered table before running the pipeline                       |\n| `--list-styles`       | —          | Show all styles in the database as a table and exit      |\n| `--add-style`         | —          | Interactively add a new style to the database and exit   |\n| `--remove-style`      | —          | Interactively select and remove styles from the database and exit |\n| `--aspect-ratio RATIO`| DB / env / `4:3` | Aspect ratio for generated image (see [supported ratios](https://ai.google.dev/gemini-api/docs/image-generation#aspect_ratios_and_image_size), e.g. `1:1`, `3:4`, `4:3`, `9:16`, `16:9`) |\n| `--add-character-mapping` | — | Interactively add a character name mapping and exit |\n| `--remove-character-mapping` | — | Interactively remove character name mapping(s) and exit |\n| `--list-character-mappings` | — | Show all character name mappings and exit |\n| `--destination-album` | DB / env   | macOS Photos album to import the generated image into    |\n| `--silent`            | off        | Suppress Rich UI; only print the output file path        |\n| `--json`              | off        | Output run results as JSON (suppresses Rich UI)          |\n| `--config`            | —          | Interactively configure settings and exit                |\n| `--history`           | —          | Show recent runs as a table and exit                     |\n| `--config-path`       | `~/.imagemine.db` | Path to the SQLite database file                  |\n| `--launchd [MINUTES]` | —          | Write a launchd plist to `~/Library/LaunchAgents/imagemine.plist` that runs imagemine on the given interval; omit `MINUTES` to be prompted. Prints the `launchctl` command to activate it. |\n\n### Examples\n\n```sh\n# Basic usage\nimagemine sunset.jpg\n\n# Pick a random photo from a Photos album\nimagemine --input-album \"Camera Roll\"\n\n# Custom output directory\nimagemine photo.jpg --output-dir ~/Desktop/imagemine-out\n\n# Tune creativity\nimagemine photo.jpg --desc-temp 1.5 --img-temp 0.8\n\n# Use a custom style prompt instead of a random one\nimagemine photo.jpg --style \"Ukiyo-e woodblock print, bold outlines, flat color\"\n\n# Generate with a specific aspect ratio\n# Must be one of: https://ai.google.dev/gemini-api/docs/image-generation#aspect_ratios_and_image_size\nimagemine photo.jpg --aspect-ratio 16:9\n\n# List all styles in the database\nimagemine --list-styles\n\n# Add a new style interactively\nimagemine --add-style\n\n# Pick style(s) interactively from a numbered table\nimagemine photo.jpg --choose-style\n\n# Silent mode — only prints the output file path\nimagemine photo.jpg --silent\n\n# JSON mode — output run results as structured JSON\nimagemine photo.jpg --json\n\n# Save an SVG of the terminal session alongside the generated image\nimagemine photo.jpg --session-svg\n\n# Show recent run history with timing sparklines\nimagemine --history\n\n# Configure API keys and settings interactively\nimagemine --config\n\n# Use a custom database location\nimagemine photo.jpg --config-path ~/work/imagemine.db\n\n# Configure settings into a custom database\nimagemine --config --config-path ~/work/imagemine.db\n```\n\n## Styles\n\nEach run applies a randomly selected visual style from a built-in library of 35+ styles. The style name and description are appended to the image prompt sent to Gemini.\n\nExample styles: Watercolor, 8-Bit Pixel Art, Ukiyo-e Woodblock, Neon Noir, Tarot Card, Vaporwave, Glitch Art, Renaissance Painting, and more.\n\n### Choosing styles interactively\n\n```sh\nimagemine photo.jpg --choose-style\n```\n\nDisplays a numbered table of all styles. Enter one number (e.g. `3`) to use that style, or a comma-separated list (e.g. `1,5,12`) to blend the selected styles into a single prompt. Each selected style's usage count is incremented.\n\n### Using a custom style prompt\n\nUse `--style` to pass a free-form style prompt directly instead of picking one at random from the database. imagemine will describe the photo, append the style text, and generate the image.\n\n```sh\nimagemine photo.jpg --style \"Risograph print, grainy ink, limited overlapping spot colors\"\n```\n\n### Listing styles\n\n```sh\nimagemine --list-styles\n```\n\nPrints a table of all styles in the database with their description and usage count.\n\n### Adding a style\n\n```sh\nimagemine --add-style\n```\n\nPrompts for a name and a description/prompt, then saves the new style to the database. It will be included in random selection on future runs.\n\n### Removing a style\n\n```sh\nimagemine --remove-style\n```\n\nDisplays a numbered table of all styles. Enter one or more numbers (e.g. `1` or `1,3,5`), review the confirmation prompt, and confirm to delete.\n\n## Character Mappings\n\nWhen imagemine picks a photo from a macOS Photos album, it reads any face-detection names associated with the photo. Character mappings let you rename these before they reach the AI prompt — for example, mapping \"John Smith\" to \"Captain America\".\n\n### Adding a mapping\n\n```sh\nimagemine --add-character-mapping\n# Input name (from Photos): John Smith\n# Mapped name (for prompt): Captain America\n```\n\n### Listing mappings\n\n```sh\nimagemine --list-character-mappings\n```\n\n### Removing mappings\n\n```sh\nimagemine --remove-character-mapping\n```\n\nDisplays a numbered list of mappings. Enter one or more numbers to remove, then confirm.\n\n## Configuration\n\nRun the interactive config wizard to set or update any value:\n\n```sh\nimagemine --config\n```\n\nThe wizard walks through each key in order, pre-populates non-secret fields with their current values, and masks API key input. Leaving a field blank keeps the existing value (or skips it if unset).\n\n\n| Key                 | Description                                                  |\n| ------------------- | ------------------------------------------------------------ |\n| `ANTHROPIC_API_KEY` | Anthropic API key (checked before env var)                   |\n| `GEMINI_API_KEY`    | Google Gemini API key (checked before env var)               |\n| `DEFAULT_DESC_TEMP` | Default sampling temperature for description generation (e.g. `1.2`) |\n| `DEFAULT_IMG_TEMP`  | Default sampling temperature for image generation (e.g. `0.8`) |\n| `CLAUDE_MODEL`      | Claude model to use for description (default: `claude-sonnet-4-6`) |\n| `GEMINI_MODEL`      | Gemini model to use for image generation (default: `gemini-3-pro-image-preview`) |\n| `INPUT_ALBUM`       | macOS Photos album to pick a random input image from         |\n| `DESTINATION_ALBUM` | macOS Photos album name to import generated images into      |\n| `ASPECT_RATIO`      | Aspect ratio for generated images (default: `4:3`); must be a ratio listed at [the Gemini docs](https://ai.google.dev/gemini-api/docs/image-generation#aspect_ratios_and_image_size) |\n\n## Apple TV screensaver\n\nYou can use imagemine to generate a living screensaver on Apple TV by continuously transforming photos from one album and depositing the results into another.\n\n### Setup\n\n1. In macOS Photos, create two albums — one for source photos (e.g. `Camera Roll`) and one for the generated output (e.g. `imagemine`). Make the output album a Shared Album so Apple TV can see it.\n\n2. Configure imagemine to read from the source album and write to the output album:\n\n```sh\nimagemine --config\n```\n\n3. Run imagemine on a schedule via launchd to keep the output album growing. Use the `--launchd` flag to write the agent configuration automatically:\n\n```sh\nimagemine --launchd 30\n```\n\nPass a number of minutes as the argument. If you omit it, imagemine will prompt you:\n\n```sh\nimagemine --launchd\n# Run interval (minutes): 30\n```\n\nBoth commands write `~/Library/LaunchAgents/imagemine.plist` and print the `launchctl` command to activate it. Pass `--config-path` to use a non-default database location:\n\n```sh\nimagemine --launchd 30 --config-path ~/work/imagemine.db\n```\n\nThen follow the printed instructions to load the agent:\n\n```sh\nlaunchctl load ~/Library/LaunchAgents/imagemine.plist\n```\n\n### Setting the screensaver on Apple TV\n\n1. Open the **Photos** app on Apple TV 4K.\n2. Navigate to **Shared Albums** or **Albums** at the top of the screen.\n3. Select the output album (`imagemine`), then select **Set as Screen Saver** and confirm.\n\nNew images added to the shared album will appear in the screensaver automatically.\n\n## Development\n\n### Setup\n\n```sh\ngit clone https://github.com/hbmartin/imagemine\ncd imagemine\nuv sync --dev\n```\n\nTo run from the local source:\n\n```sh\nuv run imagemine path/to/photo.jpg\n```\n\nRun the linters, type checker, and tests:\n\n```sh\nuv run ruff check src --fix\nuv run pyrefly check src\nuv run ty check src\nuv run pytest tests/\n```\n\n### Database\n\nEvery run is recorded in `~/.imagemine.db` by default. Use `--config-path` to specify a different location. The `runs` table tracks:\n\n| Column                   | Description                                                  |\n| ------------------------ | ------------------------------------------------------------ |\n| `started_at`             | UTC timestamp when the run began                             |\n| `input_file_path`        | Absolute path to the source image                            |\n| `resized_file_path`      | Path to the temporary resized JPEG (deleted after generation) |\n| `generated_description`  | Story + image prompt from Claude                             |\n| `description_model_name` | Claude model used                                            |\n| `desc_temp`              | Temperature used for description generation                  |\n| `desc_gen_ms`            | Description generation time in milliseconds                  |\n| `output_image_path`      | Path to the generated image                                  |\n| `image_model_name`       | Gemini model used                                            |\n| `img_temp`               | Temperature used for image generation                        |\n| `img_gen_ms`             | Image generation time in milliseconds                        |\n| `input_album_photo_id`   | Photos item ID when input was selected from an album         |\n| `style`                  | Visual style applied to the image prompt                     |\n\nA new description is generated from Claude on every run.\n\n### Terminal UI\n\nimagemine uses [Rich](https://github.com/Textualize/rich) for its terminal output:\n\n- **Labeled section rules** divide the pipeline into phases: Resize → Describe → Style → Generate\n- **Live spinners with elapsed timers** show progress during the two API calls — a `moon` spinner for Claude description generation and a `smiley` spinner for Gemini image generation\n- **Description panel** renders the generated story as formatted Markdown inside a cyan-bordered panel\n- **Style tree** shows the randomly selected style with its full description\n- **Summary panel** displays source file, style, per-step timing, total wall time, and output path\n- **`--history` table** lists recent runs with per-step timing, total time, and a proportional sparkline bar\n- **`--session-svg`** saves a styled SVG of the entire terminal session alongside the generated image\n- **Error tracebacks** are rendered with Rich syntax highlighting when an API call fails\n\n## Legal\n\nCopyright 2026 [Harold Martin](https://www.linkedin.com/in/harold-martin-98526971/). Licensed under the [Apache License, Version 2.0](LICENSE).\n\nApple, Apple TV, and Photos are trademarks of Apple Inc., registered in the U.S. and other countries.\n\nClaude and Anthropic are trademarks of Anthropic, PBC.\n\nGoogle and Gemini are trademarks of Google LLC.\n\nThis project is not affiliated with, endorsed by, or sponsored by Apple Inc., Anthropic, PBC, or Google LLC.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhbmartin%2Fimagemine","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fhbmartin%2Fimagemine","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhbmartin%2Fimagemine/lists"}