---
name: eggapi-batch-edit
description: Apply the same edit to a whole folder of images with EggAPI - white or new backgrounds, extending images to new aspect ratios, removing clutter, matching one style across a catalog, or re-rendering at a higher resolution - tested on a few images first, with a cost estimate, a resumable job log and a before/after contact sheet. Use when the user has many images to edit the same way (批量修图、批量换背景、白底图、扩图、统一风格、批量处理).
---

# Batch image edits

Run one edit across a folder of images reliably: test it on a few, agree the cost, run the rest in waves, check the results and hand over a before/after sheet. Reply in the user's language. Write model prompts in English; put any text that should appear in an image in quotes, in its target language.

## EggAPI basics

This skill uses the EggAPI MCP server, usually added under the name `eggapi`: `list_models`, `generate_image`, `generate_video` and `get_task` (in Claude Code they show up as `mcp__eggapi__*`). If these tools are missing, stop and send the user to https://eggapi.ai/connect to add the server.

- **Models.** Call `list_models` once at the start. Use the model IDs this skill names when they are listed; otherwise pick the closest model with the same `generation_type`. `unit_price_usd` is the price per image, or per second of video; `unit_price_by_resolution` overrides it for a given `resolution`.
- **Local files.** The generate tools only accept public `http(s)` URLs. Upload local files first (up to 20 MB per image):

  ```bash
  curl -sS https://api.eggapi.ai/v1/uploads \
    -H "Authorization: Bearer $EGGAPI_API_KEY" \
    -F "files[]=@./photo-1.jpg" -F "files[]=@./photo-2.jpg"
  ```

  The URLs are in `data.files[].url`. If `EGGAPI_API_KEY` is empty in the shell, ask the user to export it; never ask for the key in the chat. Uploaded files can be opened by anyone who has the URL, so say so before uploading anything private.
- **Tasks are async.** `generate_image` and `generate_video` return a `task_id` at once. Submit every independent task first, then poll `get_task` for each until `done` is true: every 5-10 s for images, 10-15 s for videos (usually 1-3 min). If a generate call already returns `urls`, no polling is needed.
- **Always pass** `aspect_ratio` (the default is 16:9) and, for video, `duration` (4-15 s). Supported ratios: `1:1`, `3:4`, `4:3`, `9:16`, `16:9`, `21:9`.
- **Edit models return one image per call.** For more variants, call again; `num_outputs` only applies to text-to-image models.
- **Output URLs work as inputs.** Pass a finished image's URL straight into the next edit or video call; no re-upload needed.
- **Save everything.** Download each output as soon as its task completes, into `eggapi-output/<project>/` under the current directory, with `curl -sSL -o <file> <url>`: some output links expire after 24 hours, and some file hosts reject other HTTP clients. Keep the extension from the URL and use descriptive file names.
- **Cost.** Show the plan with an estimated cost before generating and wait for a go-ahead, unless the user already said to go ahead. At the end, report each task's `cost` and the total.
- **Errors.** `insufficient balance`: ask the user to top up at https://eggapi.ai/dashboard. `temporarily unavailable`: switch to another model of the same type. A `failed` task: read `error`, adjust the prompt if it points at the content, and retry once.

Only edit images the user owns or has the rights to. Do not remove watermarks, signatures or credits from other people's images.

## 1. Collect the inputs

Ask only for what is missing:

- **The folder** (or a list of files).
- **The edit**: one of the recipes below, or the user's own description.
- **Output**: format (PNG or JPEG), size, and whether to keep the original file names (default yes).

Count the images and find any that are too large to upload:

```bash
find ./photos -maxdepth 1 -type f \( -iname '*.jpg' -o -iname '*.jpeg' -o -iname '*.png' -o -iname '*.webp' \) | wc -l
find ./photos -maxdepth 1 -type f -size +20M
```

Shrink files over 20 MB before uploading, keeping the originals: `magick in.jpg -resize '4096x4096>' -quality 92 small/in.jpg`, or on macOS `sips -Z 4096 in.jpg --out small/in.jpg`.

## 2. Pick the recipe

Use `google/nano-banana-pro/edit` by default and `bytedance/seedream-v5.0-pro/edit` as the alternative. Start every prompt with what must not change.

| Recipe | Prompt core |
| --- | --- |
| White background | Keep the subject exactly as it is. Replace the background with pure white (#FFFFFF) with a soft natural shadow under the subject. Change nothing else. |
| New background | Keep the subject exactly as it is. Place it in {scene}, matching the light direction, color and shadows to the new scene. |
| Extend to a new ratio | Extend the image to fill the new frame by continuing the background naturally. Do not stretch, crop or change the subject. (Pass the target `aspect_ratio`.) |
| Remove clutter | Remove {objects}. Fill the area so it matches the surroundings. Change nothing else. |
| Match a catalog style | Pass a style reference image second: Keep the subject of the first image exactly. Match the lighting, color grading and background of the second image. |
| Higher resolution | Recreate this image at a higher resolution with sharper detail. Change nothing. (`resolution: "4k"`; Seedream 5.0 Pro stops at 2k, so use `bytedance/seedream-v4.5/edit` as the 4k alternative.) |
| Change one piece of text | `openai/gpt-image-2/edit`: Replace the text "{old}" with "{new}" in the same position, font and color. Change nothing else. |

Two cautions to share with the user:

- **Higher resolution redraws the image.** Small text, faces and fine textures can change; it does not replace a true upscaler.
- **Aspect ratio**: models output only `1:1`, `3:4`, `4:3`, `9:16`, `16:9` and `21:9`. Read each source's size (`magick identify -format "%w %h\n" f.jpg`, or `sips -g pixelWidth -g pixelHeight f.jpg`) and pass the closest ratio; crop back to the exact size afterwards if needed (step 6).

Match `resolution` to the source: `1k` is about 1024 px and `2k` about 2048 px on the long side.

## 3. Test on a few images

Pick three images that represent the folder, including the hardest ones: hair, glass or other transparent parts, reflections, fine text, busy backgrounds. Run the edit on them, show each next to its original, and tune the prompt until the user is happy.

Then estimate the full run: number of images x the image price at the chosen resolution. Wait for the go-ahead. For more than 50 images, also say roughly how long it will take.

## 4. Run the batch

- **Upload in groups** of about 20 files per request.
- **Submit in waves** of 10-20 tasks, poll them until done, then submit the next wave. If a call is rate limited, wait the time it gives and carry on.
- **Keep a job log** in `eggapi-output/<batch-name>/jobs.csv` with the columns `file,upload_url,task_id,status,output,cost`, updated after every wave. If the run stops, read the log and continue with the files not yet completed instead of starting over.
- **Download** each output into `eggapi-output/<batch-name>/after/`, keeping the source's base name.

## 5. Check

If you can view images, check every output, or for large batches a sample plus every image that looks off at thumbnail size: the subject is unchanged, edges are clean (hair, transparent parts), there are no artifacts or extra objects. Re-run failures once with the problem named in the prompt. List any that still fail instead of delivering them.

## 6. Finish the files

If ImageMagick is installed, convert or crop to the exact output size the user asked for:

```bash
cd eggapi-output/<batch-name>
mkdir -p final
for f in after/*; do magick "$f" -resize 2000x2000^ -gravity center -extent 2000x2000 -quality 92 "final/$(basename "${f%.*}").jpg"; done
```

Make a before/after contact sheet, one pair per row:

```bash
mkdir -p pairs
for f in after/*; do
  b=$(basename "${f%.*}")
  src=$(ls <source-folder>/"$b".* | head -1)
  magick "$src" "$f" -resize 600x600 -background white -gravity center -extent 600x600 +append "pairs/$b.jpg"
done
magick montage -label '%t' pairs/*.jpg -tile 1x -geometry +0+10 contact-sheet.jpg
```

Without ImageMagick, skip these steps and say so.

## 7. Deliver

Hand over `eggapi-output/<batch-name>/` with `after/` (and `final/` if made), `contact-sheet.jpg`, `jobs.csv`, and the list of files that failed. Report the number of images, the cost per image and the total.
