Skip to content

Releases: RZ-Logic/clean-thumbnail-skill

Clean Thumbnail v0.9.1

Choose a tag to compare

@RZ-Logic RZ-Logic released this 19 Oct 22:09

A review pass: about 70 verified defects fixed, several of them found by outside reviewers and a multi-agent review. The default look changes, so read the first section before you compare old and new thumbnails.

The default look changed

  • The shade is automatic. Without --shade, the type side is darkened as little as it can be while every element keeps 7:1 contrast (between 0.35 and 0.88), so more of the picture shows. A short title shades less of the frame. --shade N, or "shade" in the channel file, keeps the old fixed amount. Contrast is now scored at the worst letter-sized slice, so one letter on a bright patch fails the line, and the printed contrast figures are lower than before.
  • Dark fills keep their edge. Flat dark fills (the color taken from the image, slabs beside narrow art, solid panels) are lifted to at least 1.2:1 against YouTube's dark page, so a neutral becomes charcoal #222222 instead of near-black. An explicit --bg that is too dark is kept, with a note.
  • Centered panel titles on 16:9 are fitted narrower (about 0.48 of the width), so they stay left of the duration badge; long panel titles may wrap to two lines.
  • Every demo image and preview in demo/ is re-rendered with the new default.

New flags

  • --no-trim keeps the capture and panels whole instead of trimming letterbox bars. A logo or product on a flat black field is no longer trimmed in any case.
  • --no-system-fonts and --no-logo-white override a saved true in the channel file for one run.
  • The preview gets a boxes tile when --subject-box or --inset-box is given (subject box cyan, inset box amber), so you can check the box holds the face or screen.

Inputs and output files

  • NVIDIA and Xbox Game Bar HDR captures (JPEG XR, sometimes named .jpg) get a specific error that says to export SDR PNG or JPEG. HEIC opens with pillow-heif; AVIF and oversize inputs get specific messages. Inputs up to 400 MP are accepted.
  • Embedded ICC profiles (Display P3, Adobe RGB, CMYK) are converted to sRGB.
  • -o is checked before rendering and guarded by file identity (hard links, short names, junctions), and every output is written through a temp file, so an interrupted run leaves nothing half-written. Any image extension on -o is replaced.
  • Piped output is UTF-8.
  • 16:9 posts write <stem>_1280.jpg and a Facebook-style preview card instead of the YouTube sheet.

Type

  • Tracked type no longer collides at "fi" and "ff"; accents stay with their letters.
  • Right-to-left and joining scripts (Hebrew, Arabic, Indic, Thai) are drawn shaped, without tracking.
  • A \n in --label splits the hook like ·; label boxes, kickers and subtitles show line breaks as spaces.
  • On a light --bg, kicker, subtitle and post body and details turn near-black, auto colors darken, and a white title on a light solid panel is told to use a dark --title-color instead of a darker --bg.
  • Label fonts marked as not capitals-only (gothic, brush) keep the case you write, in panel labels too.
  • New warnings: no glyph in the label font (the middle dot included), a title wider than the type column at its smallest size, oldstyle figures, big type that is too small or has strokes too thin on the 168 px tile, and the --logo replaces the title note (previously silent).

Layout

  • On 4:5 and 9:16, --band auto also moves the band to the top when an inset sits under the bottom band's type, and --text-side and --focus say so when they are ignored.
  • Warnings name a fix that has been confirmed by re-rendering with it; --subject-box warnings print a computed --crop (and --band).
  • New 9:16 warning when a cut-out's face falls under the Reels/Shorts caption area; cut-outs are sized for head clearance.
  • The duration-badge warning names a fix, and a 120 px tile note says when the badge covers part of an element.
  • 4:5 and 9:16 panel labels sit at their panel's corner.

Posts

  • Long words and links wrap by width, breaking after / - _ ? & = with no hyphen added; the fit shrinks by width as well as height.
  • The CLI prints the laid-out lines under post text: (|+ marks a break inside a word, [does not fit] marks a line out of frame).
  • A 9:16 --backdrop solid post that would leave the photo under 20% of the frame moves the band to the top.
  • Post warnings, the headline's included, stop telling you to cut the user's words and offer a wider format or an approved shorter form instead.
  • A typed \n inside a Windows path stays text; --details breaks only at · with spaces around it.

Skill and docs

  • SKILL.md is shorter (about 2,000 words, down from about 2,700). The full flag, channel-key, notes and warnings reference moved to references/flags.md; the workflow and decisions stay in SKILL.md.
  • Test & Compare is described as 16:9 long-form only (not Shorts, Premieres, scheduled lives, made-for-kids or private videos); for 9:16 and 4:5 the skill ships one variant or lets you choose by eye.
  • The Reels/Shorts safe zone is called a conservative preset, with its source (Meta's Reels ad guide), instead of a platform rule.
  • New checks in the skill: look for HUD, performance overlays, button prompts and toasts in captures (the lighter shade shows more of the frame); ask what happened or changed when the title names only a topic; HDR captures in step 1; --channel and the working-folder rule for the channel file.
  • channel.example.json holds just the aspect, and step 4 saves only the aspect, so the stock file no longer triggers post-mode notes.
  • type-rules.md: fixed the broken Posts table row, reworded "never repeats the title", replaced the vague Ronaldo example, and described stacked hooks as fitted per line.
  • README: the Stillroom command drops the inert --title and --title-font; --aspect replaces the saved formats for that run; feed width is 360 px (300 px for 9:16 posts).
  • agents/openai.yaml has a short description that covers posts and Facebook/Instagram.
  • skill/clean-thumbnail/ now carries its own LICENSE.
  • The upscale warning says to recapture at 1440p or higher; it no longer names an outside upscaler.

Tests

  • 323 tests (191 in v0.9.0) and 286 mutants, every one caught by a failing assertion or, where the old bug was itself an exception, by that exception; any other crash now fails the check. The suite passes on Pillow 10.4 (Python 3.8) through Pillow 13. CT_FAST=1 skips the 8 slowest tests. tools/build_zip.py builds a byte-identical ZIP on any machine, and the tests no longer write into dist/.

Credits

Thanks to the outside reviewers who read the skill, the renderer and the README and sent reproducible findings, and to the review passes whose reports drove this release.

Clean Thumbnail v0.9.0

Choose a tag to compare

@RZ-Logic RZ-Logic released this 14 Oct 01:20

Clean Thumbnail v0.9.0 adds a post mode. The skill was built for video thumbnails, where the video title carries the message and the image holds a few words. Used for a Facebook post, that cut the message down to a hook and pushed the rest into the caption. A post has no video title: its image text is the message.

New

  • --mode post with --body TEXT and --details TEXT. The headline goes in --title, the message in --body (wrapped, in the label font) and when and where in --details. The script never cuts, reorders or moves the words; every word is checked to be laid out, in order.
  • A readability check instead of a word cap. The body has to read on a 360 px phone feed (8 px cap height). If it wouldn't, the script warns and names the fix (shorten, split into headline, body and details, or use a taller format); it never truncates.
  • Post defaults: one 4:5 image, not an A/B pair, unless --aspect or --lead is given. A channel file's thumbnail formats are not applied to posts. Each render prints a post text: line with the body and details sizes on the phone feed.
  • --backdrop fade|solid. fade (default) darkens the photo into the shade behind the type, as before. solid keeps the photo clean and sets the type on an opaque panel in the --bg color, with a hard edge. It works in every format, for thumbnails and posts, and can be saved as the channel default.
  • Three post demos in the README (a creator workshop, a café event, a studio offer with its logo), all fictional and rendered straight from licensed Pexels photos.
  • Agent instructions: SKILL.md now decides "thumbnail or post?" first. For a post it keeps the user's words, fixes only spelling and capitals, and asks before any cut. The type rules have a Posts section.

Existing thumbnails are unchanged: with the default --backdrop fade, output matches v0.8.2 byte for byte on 96 render cases and every demo.

Install

  • Agent Skills ZIP: download clean-thumbnail.zip below.
  • Claude Code: copy skill/clean-thumbnail/ to ~/.claude/skills/clean-thumbnail/.
  • Codex: copy it to ~/.codex/skills/clean-thumbnail/.

Verification

191 tests, also run with every system font hidden; 105 mutants caught.

Clean Thumbnail v0.8.2

Choose a tag to compare

@RZ-Logic RZ-Logic released this 13 Oct 23:00

Fixes from an outside review of v0.8.1. Thumbnails made without a channel file are unchanged.

Fixed

  • A channel file no longer blurs plain thumbnails. SKILL.md has the agent create clean-thumbnail.json from references/channel.example.json, which sets "push": 0.5. That value was applied to every capture, so thumbnails without a cut-out came out blurred and darkened. --push now only softens the photo behind a --subject cut-out, as its help text says.
  • Contrast advice names the right flag. When a hand-picked big-type color is too dark or too dim, the warning now says --title-color; it used to say --accent.
  • The summary line and the warning agree. A failing contrast of 4.46:1 printed as contrast 4.5:1 in the summary and 4.4:1 in the warning; both now show 4.4.
  • rembg runs once per subject. With an opaque subject photo, background removal ran again for every variant and format (up to six times with --aspect all); it now runs once.

Docs

  • The README options table now lists -o, --style, --panel/--panel-label, --kicker/--subtitle, --feather, --shade and --bg, and the What ships table lists fonts/catalog.json and agents/openai.yaml. The top links include the official-logo example.
  • SKILL.md lists the same flags, says to keep --subject-box unchanged when re-running with a suggested --crop, and that a second run for 4:5 and 9:16 can reuse the same -o.

Verification

155 tests, also run with every system font hidden; 71 mutants caught. Golden renders match v0.8.1 except the corrected --title-color advice.

Clean Thumbnail v0.8.1

Choose a tag to compare

@RZ-Logic RZ-Logic released this 13 Oct 21:31

A fix release for v0.8.0. Use this zip; the v0.7.0 and v0.8.0 zips are rejected by claude.ai's skill upload.

Fixed

  • claude.ai upload: the zip was rejected with "Zip file contains path with invalid characters". Eight bundled variable fonts had square brackets in their file names (Outfit[wght].ttf, Google Fonts' naming); they are now Outfit-VariableFont_wght.ttf and so on. tools/build_zip.py now refuses to build when any path uses characters outside A-Z a-z 0-9 . _ - /, and a test checks the zip.
  • Preview captions on machines without raqm: the CI runners for macOS and Windows lay text out without kerning, so the word space in the small preview captions came out narrower than intended and a test failed there. Captions now use a minimum word space of 0.3 em, the same with or without raqm.

The thumbnails themselves are unchanged from v0.8.0; only the preview sheets differ.

Install

  • Agent Skills ZIP: download clean-thumbnail.zip below and upload it.
  • Claude Code: copy skill/clean-thumbnail/ to ~/.claude/skills/clean-thumbnail/.
  • Codex: copy it to ~/.codex/skills/clean-thumbnail/ (delete the old folder first, so the renamed fonts don't sit next to the old files).

Verification

151 tests, also run with every system font hidden; 67 mutants caught.

Clean Thumbnail v0.8.0

Choose a tag to compare

@RZ-Logic RZ-Logic released this 13 Oct 21:11

Clean Thumbnail v0.8.0 fixes the biggest gap an outside review found: the renderer couldn't tell where a face was, so the type or its shade could land on it without a warning. It also makes the default type the same on every machine.

New

  • --subject-box x0,y0,x1,y1. Mark the face from the brows to the chin (or a product's label), the same way as --inset-box. The 16:9 type takes the side that keeps it clear, the 4:5 and 9:16 crops center on it (vertically too, on tall captures), and the 9:16 type band moves to the top when that keeps the face clearly more in view. Each variant prints a subject box: line, and a warning fires when the face still ends up shaded, under type or out of frame, naming one fix to try: a --crop, --focus, --text-side or --band. Without a box, the script still finds the subject by edge activity, which can't recognize a face.
  • --band auto|top|bottom places the type band on 4:5 and 9:16 by hand.
  • Bundled fonts by default. The default title is Playfair Display Bold (serif) or Outfit Bold (sans), with Outfit SemiBold in the label box and the preview captions, so the same command gives the same type on Windows, macOS and Linux. --system-fonts (or "system_fonts": true) brings back the installed faces of v0.7.0 (Bodoni MT, Bahnschrift, Didot) and reproduces v0.7.0 masters on the same machine.
  • Checks you can run. python tools/mutate.py puts 66 fixed bugs back one at a time and confirms each test fails. GitHub Actions runs the suite on Windows, macOS and Linux, plus Python 3.8.

Changed

  • The default look changes: Bodoni MT and Bahnschrift give way to Playfair Display Bold and Outfit. Use --system-fonts to keep the old look.
  • The duration-badge corner now matches the badge as drawn on the 168 px up-next tile, so right-side type stays clear of it from that size up.
  • Preview captions and the badge are drawn sharper, with readable word spacing.
  • Two tests no longer depend on fonts only installed on some Windows machines; the suite passes with every system font hidden.
  • The Reels warning for two comparison panels no longer tells you to use two panels when you already do.
  • render() is split into stages with no change in output (checked against hashed renders of 96 cases and every demo).
  • Docs: the creator photo leads the README, Claude Code install paths are listed, the stale "different font per video" rule is gone, and Test & Compare is described as YouTube documents it (up to three thumbnails, winner by watch time).

Install

  • Agent Skills ZIP: download clean-thumbnail.zip below.
  • Claude Code: copy skill/clean-thumbnail/ to ~/.claude/skills/clean-thumbnail/.
  • Codex: copy it to ~/.codex/skills/clean-thumbnail/.

Needs Python 3.8+, NumPy and Pillow.

Verification

151 tests, also run with every system font hidden; 66 mutants caught. The README demo commands reproduce the shipped images byte for byte with the same Pillow build; the type itself no longer depends on the machine.

Clean Thumbnail v0.7.0

Choose a tag to compare

@RZ-Logic RZ-Logic released this 13 Oct 18:16

First public release of Clean Thumbnail, an Agent Skill and local renderer for restrained, editorial thumbnails: real images carry the mood, the type stays quiet. No glows, arrows, stickers, color washes or image-model scenes.

What it does

  • Any kind of video, no per-type layouts. Every thumbnail is real images in four roles: a background, side-by-side comparison panels, a cut-out subject matched to the photo behind it (color cast, black and white points, sharpness, grain), or an inset such as a game frame on a monitor.
  • Text from the title. The skill turns a video title into a short subject and hook and renders an A/B pair for YouTube's Test & Compare.
  • Every format from the same images. YouTube 16:9 masters up to 3840×2160 plus a 1280×720 phone copy under 2 MB; Facebook and Instagram feed 4:5; Reels, Shorts and Stories 9:16 inside the safe zone. Formats are asked once and saved in clean-thumbnail.json.
  • The title's own look. The official logo first, else the closest of 16 bundled open-licensed fonts, matched in weight and letter spacing (--title-font outfit@Light --title-tracking 0.12), else the channel font.
  • One color at most. White by default; --title-color auto takes the image's signature color and lifts it just enough to read.
  • Room for the type. --crop narrows centered key art so the subject moves to the far side.
  • Checks, not guesses. Per-element WCAG 4.5:1 contrast, the duration-badge corner, the Reels safe zone, letterbox and pillarbox trimming, feed-size and squint previews, and clear errors for bad inputs.

Install

  • Agent Skills ZIP: download clean-thumbnail.zip below and upload it to a client that accepts skills.
  • Codex: copy skill/clean-thumbnail/ to ~/.codex/skills/clean-thumbnail/.
  • Direct: python -m pip install numpy pillow, then run skill/clean-thumbnail/scripts/thumb.py (see the README Quickstart).

Needs Python 3.8+, NumPy and Pillow. rembg is optional, for removing backgrounds from subject photos.

Verification

124 tests (python -m unittest discover -s tests). Key fixes are mutation-tested: putting each bug back makes its test fail. The demo commands in the README reproduce the shipped images byte for byte.

Limits

The checks catch mechanical failures; they don't predict click-through or pick the best image. A matched font is close in spirit, not the real lettering. On 9:16 the type sits mid-frame for the safe zone, so vertical formats need a frame with the face in the top third. The images in demo/ are third-party art and photos credited in the README; they are not covered by the MIT license.