Communitygithub.com

fangdididi/asset-size-matrix

Turn one finished key visual (poster, launch graphic, cover, thumbnail, or a short video) into every size a launch or campaign needs, without cutting off faces, logos or headlines. Builds a dated slot list for the destinations (link cards, video thumbnails, feed posts, 3:4 covers, 9:16 stories and shorts, banners, app icons, podcast covers), marks what must survive on the master, plans a crop for each slot inside that slot's UI-safe area, flags the slots that need the layout recomposed or a bigger master, checks text is still readable at the size people actually see it, then checks every exported file (pixel size, format, file size, codec, frame rate, duration, loudness) and hands over a contact sheet. Use when someone says "make this work for every platform", "I need all the sizes", "resize this banner for X/Instagram/YouTube/WeChat", "export a launch kit", or "why does my cover get cut off". It adapts and checks; it does not invent the design and never uploads anything.

What is asset-size-matrix?

asset-size-matrix is a Claude Code agent skill that turn one finished key visual (poster, launch graphic, cover, thumbnail, or a short video) into every size a launch or campaign needs, without cutting off faces, logos or headlines. Builds a dated slot list for the destinations (link cards, video thumbnails, feed posts, 3:4 covers, 9:16 stories and shorts, banners, app icons, podcast covers), marks what must survive on the master, plans a crop for each slot inside that slot's UI-safe area, flags the slots that need the layout recomposed or a bigger master, checks text is still readable at the size people actually see it, then checks every exported file (pixel size, format, file size, codec, frame rate, duration, loudness) and hands over a contact sheet. Use when someone says "make this work for every platform", "I need all the sizes", "resize this banner for X/Instagram/YouTube/WeChat", "export a launch kit", or "why does my cover get cut off". It adapts and checks; it does not invent the design and never uploads anything.

Works with~Claude Code~Codex CLI~Cursor
npx skills add fangdididi/asset-size-matrix

Ask in your favorite AI

Open a new chat with this agent skill pre-loaded.

Documentation

What does asset-size-matrix do?

One master, every slot, nothing important cut off, and a receipt for each file.

What this skill is

A launch rarely needs one image. It needs a link preview, a video thumbnail, a square post, a portrait post, a 3:4 cover, a vertical story, a profile banner, an app icon, a repo preview, maybe a vertical video. Each one has its own pixel size, its own file rules, and its own interface overlay: the like column on the right of a vertical feed, the duration badge in the corner of a thumbnail, the avatar sitting on top of a banner, the rounded mask on an icon.

People usually handle this by dragging a crop box around a dozen times. The results are familiar: a headline sliced in half on the 9:16 version, a logo hidden under the avatar, text that was readable on the 4K master and is three pixels tall in the feed, a thumbnail rejected for being 2.3 MB, a short that plays 8 dB quieter than everything around it.

This skill makes the job a table. Every destination becomes a slot card with numbers and a date. The master gets marked once: which boxes must survive. A small planner computes, for each slot, the widest crop that keeps those boxes inside the slot's safe area, and says plainly when no crop can work. Then every exported file is checked against its card.

The problem it solves

  • Crops are decided by eye, one at a time, so they are inconsistent and nobody can say why a given crop was chosen.
  • Safe areas are forgotten until the post is live and the call-to-action sits under a button.
  • "Just crop it" is applied to slots where cropping cannot work (a wide layout squeezed into 9:16), so the result is either cut off or shrunk to illegibility.
  • Text size is judged on the master, not at the size the slot is actually displayed.
  • File rules (format, weight, codec, frame rate, loudness) are discovered by upload errors.
  • Platform numbers are copied from old blog posts with no date and no source.

When to use

Use it when:

  • one design must be delivered in several sizes or to several platforms;
  • someone asks for a "launch kit", "social pack", "all the sizes", "banner set";
  • a cover or thumbnail keeps getting cut off or blurry after upload;
  • a short video must also exist as a vertical, square and wide version;
  • you are about to export a batch and want proof every file meets its spec.

Do not use it to create the design from nothing (make the master first), to edit video content (cutting, captions, color), or to publish. It can tell you that a slot needs a new layout; the new layout is a design task.

What you need

  • The master: ideally the editable source (Figma/PSD/HTML/SVG/project file) plus a flat export at the largest size available. Pixels alone are fine for crop-only slots.
  • The list of destinations, or the goal ("launching on X, Instagram and our blog").
  • For video slots: the video file, and ffmpeg/ffprobe installed if you want automatic checks.
  • Python 3.8+ for the helper scripts/matrix.py (standard library only).

Step by step

1. Take stock of the master

Record in master.json (see examples/master.json):

  • pixel width and height, and whether it is a still or video;
  • whether an editable source exists (this decides how expensive a REFLOW is);
  • the largest version available. Never plan from a downsized copy someone pasted in chat.

If the master is smaller than the biggest slot, say so now; it will show up as UPSCALE later.

2. Write the slot list, with dates

Create slots.json (start from examples/slots.json). One card per slot:

fieldmeaning
idfile name stem of the export, e.g. video-thumb -> video-thumb.jpg
w, hdelivered pixel size; exact: false means "at least this, same aspect"
safetop, right, bottom, left insets in slot pixels that the platform UI covers
dropnamed boxes that should not appear in this slot (e.g. headline on an icon)
fitwide (default, keep as much context as possible) or tight (fill the safe area)
display_whow wide the slot is really shown, in CSS px, e.g. a thumbnail in a grid
min_text_pxsmallest cap height that is still readable at display_w
formats, max_kballowed file types and weight cap
video fieldsvideo_codec, audio_codec, pix_fmt, fps range, min_s/max_s, sample_rate, lufs (+lufs_tol), true_peak_max
sourcewhere the numbers came from

Rules for the list:

  • Put as_of (today's date) at the top. Sizes and overlays change; a card without a date is a rumor.
  • Check each card against the platform's own current help page or downloadable template. If you cannot verify a number, keep it but write "source": "unverified" and say so in the hand-off.
  • Ask about slots only when the destination is unclear. One bundled question beats five: "I'll make link card, thumbnail, square, 9:16 story and banner. Add or remove any?"

3. Mark the master

Still in master.json, list boxes as [x, y, w, h] in master pixels:

  • keep: what must be visible in every slot that does not drop it (product, face, key art);
  • text: each text block with its cap_px (height of a capital letter on the master);
  • logo: the mark;
  • focus: a point to center on when nothing is marked.

Get boxes by measuring in the design tool, reading the layer bounds from the source file, or by opening the image and estimating carefully. Pad each box by a few percent; a box that hugs a face cuts the chin off in practice.

4. Plan every slot

python3 scripts/matrix.py plan --master master.json --slots slots.json

For each slot you get a verdict:

  • CROP: a crop + scale keeps everything required inside the safe area. The row includes the crop rectangle and a ready ffmpeg filter (crop=w:h:x:y,scale=W:H).
  • UPSCALE: a crop works but enlarges the master. The row says what master size is needed. Ask for a bigger export or a vector logo instead of shipping a soft image.
  • REFLOW: no crop can work, or text would be unreadable at display size. If the row includes art_only, the artwork still crops cleanly and only the listed text/logo needs to be re-set for this shape. Otherwise the composition itself has to change.

Show the user the table before exporting anything. It is the cheapest moment to change your mind.

5. Resolve each REFLOW

Pick the lightest fix that works, in this order:

  1. Re-set the type: crop the art with the art_only rectangle, then place the headline and logo again inside the slot's safe area, at a size that passes min_text_px.
  2. Restack: wide layouts (text left, art right) become tall ones (art top, text below), from the editable source, keeping the same fonts, colors and spacing ratios.
  3. Extend the canvas: widen the background in the source file (or with a plain brand color) so the art fits the safe area, rather than shrinking the art.
  4. Shorten for small slots: icons and avatars carry only the mark; a 3:4 cover in a two-column grid may need a shorter headline. Never rewrite copy yourself; propose the shorter line and let the owner approve it.

Re-run plan after each change until every slot is CROP or a deliberate, explained exception.

6. Export

  • Crop-only slots: apply the planned filter, for stills or video alike: ffmpeg -i master.png -vf "crop=...,scale=..." link-card.png.
  • REFLOW slots: export from the editable source at the exact slot size.
  • Name every file <slot id>.<ext> in one folder, so the checker can find it.
  • Stills: sRGB, no transparency where the platform flattens it onto an unknown color, quality lowered step by step only until max_kb is met.
  • Video: even width and height, yuv420p, the frame rate of the source unless the card says otherwise, loudness normalized to the card's target. For a size cap, compute the bitrate: python3 scripts/matrix.py budget --seconds 58 --max-mb 50.
  • More recipes in references/export-recipes.md.

7. Check every file

python3 scripts/matrix.py check --slots slots.json --dir out/ --loudness

Each slot comes back PASS, FAIL, CHECK (something could not be measured) or MISSING. Fix mechanical failures freely (wrong size, format, weight, pixel format, sample rate). Failures that change content (shorter duration, a tighter crop, louder audio that lifts background noise) need the owner's choice: state the option and its cost.

8. Look at it, at real size

The checker cannot see. Build a contact sheet that shows every slot at its display_w, with the safe area outlined, and open it:

python3 scripts/matrix.py sheet --slots slots.json --dir out/   # writes out/contact-sheet.html

Look for: text crossing the safe line, faces cut at the joints (chin, top of head, hands), the logo on a busy background, two slots that look like different brands.

9. Hand over

Deliver the folder plus a short manifest:

Kit: Tidepool launch, slots as_of 2026-10-24 (2 cards unverified: note-cover, article-cover)
link-card.png       1200x630   184 KB  PASS  crop
video-thumb.jpg     1280x720   402 KB  PASS  reflow: headline re-set at 96 px cap
story-vertical.png  1080x1920  1.1 MB  PASS  reflow: restacked, canvas extended
app-icon.png        1024x1024   61 KB  PASS  from vector logo (raster was 1.6x too small)
vertical-video.mp4  1080x1920  21 MB   PASS  -14.2 LUFS, -1.3 dBTP, 30 fps, 41.0 s
Look: contact-sheet.html (all slots at display size)

Examples

"Make this launch banner work everywhere." Master 4000x2250, headline left, phone mock-up right. Plan: link card and repo preview CROP; thumbnail REFLOW (headline only 13.5 px tall at grid size, needs 14); square, portrait and 3:4 REFLOW with an art_only crop (re-set headline under the phone); 9:16 REFLOW without art-only (the mock-up is too wide for the safe column, so extend the canvas and restack); app icon UPSCALE (use the vector logo). See examples/plan.output.md.

"YouTube keeps rejecting my thumbnail." One slot. The check shows 2.4 MB against a 2 MB cap and 1280x721. Re-export at 1280x720, JPEG quality lowered from 95 to 88: 1.3 MB, PASS.

"Same short for Reels, Shorts and a wide YouTube cut." Three video slots. Vertical slots CROP from the 16:9 master only because the speaker is centered; the wide cut is the master. The check finds 44.1 kHz audio (WARN) and -21.9 LUFS (FAIL against -14); normalize, re-export, re-check. See examples/check.output.txt.

Tips

  • Mark the master once and keep master.json with the design file; the next campaign reuses it.
  • When two platforms share a shape, still give them separate cards if their overlays differ.
  • Prefer one conservative safe box for vertical video if one export must serve several feeds.
  • A crop that passes the numbers but cuts through a person's joint still fails; trust the look step.
  • fit: tight is for marks and icons; everything else should keep context (wide).
  • Keep unverified numbers visible in the manifest instead of quietly trusting them.
  • Re-check after every re-export, not just the file you changed: batch tools overwrite neighbors.

Related Skills