---
name: ad-resizer
description: Resize one ad image or video into every placement (9:16 Stories / Reels / TikTok, 1:1 and 4:5 feed, 16:9 YouTube / web) with smart crop or a blurred pad, safe-zone previews that show where platform UI covers the ad, and AI outpainting with Kenerate expand_image when a crop would cut too much. Use when the user wants an ad, banner, poster or creative in other sizes or aspect ratios, needs placements for Meta / TikTok / YouTube, or asks to check safe zones.
compatibility: Needs the Kenerate MCP server (expand_image, upload_media) and Python 3.9+ with Pillow and ffmpeg.
metadata:
  author: kenerate
  version: "1.0"
  kenerate-tools: "expand_image upload_media estimate_cost wait_for_generation"
---

# Ad resizer

`scripts/resize.py` decides per format: crop when little is lost, otherwise a blurred pad, flagged for
`expand_image` (outpainting). Rules: [references/KENERATE.md](references/KENERATE.md) (models and voices: [references/MODELS.md](references/MODELS.md), or the free `pick_model` / `pick_voice` tools).

## Ask the user
- The ad (Kenerate url, or a public link to `upload_media`; a local file works for the script alone).
- Which formats (default `9:16,1:1,4:5,16:9`) and where the subject is, if it is off-centre (`--focus x,y`).

## 1. First pass (local, free)
```
python <skill-dir>/scripts/resize.py --input "<ad url or file>" --formats 9:16,1:1,4:5,16:9 \
  --name <project> --out-dir kenerate-out/ad-resizer
```
Show the `*_safezone.jpg` previews: red = covered by platform UI (approximate zones: 9:16 top 14% / bottom 22% /
right 12%, feeds 5% margins, 16:9 player bar). A `warning` in the result means busy detail (often text or a logo)
sits under the UI. Tell the user and suggest moving the text or using another crop focus.

## 2. Outpaint where a crop hurts (Kenerate)
`RESULT_JSON.needs_expand_image` lists the formats where a crop would lose more than `--max-crop` (22%). For each one:
- `expand_image(image_url=<the ad's Kenerate url>, aspect_ratio="<format>")` (default model `nano-banana-2-fast`; use
  `prompt` only to steer what fills the new area, e.g. "continue the studio backdrop"). Text near the edges can get
  painted over or duplicated, so check the results.
- It's charged per call (`variations` up to 2). Say how many formats you'll expand and confirm; `estimate_cost("expand_image", {...})` gives the price.
- `wait_for_generation("image-expand", id)`.

## 3. Final pass with the outpainted versions
```
python <skill-dir>/scripts/resize.py --input "<ad>" --formats 9:16,1:1,4:5,16:9 \
  --expanded "9:16=<expanded url>" --expanded "16:9=<expanded url>" --name <project>
```

## Video ads
The same command works on MP4s (crop or blurred pad per format; `expand_image` is for stills only). Keep the subject
centred, or use `--focus 0.5,0.35` to bias the crop up.

## Output
`<name>_9x16.jpg|png|mp4`, `<name>_1x1…`, plus a `_safezone.jpg` for each format. The report lists the crop loss,
the mode used and any warnings.

## If something fails
A failed expand_image job is refunded. Keep the blurred-pad version and ask before retrying with
`model="nano-banana-2"` or a short `prompt`.
