Install any skill in seconds. Free to start, no credit card required.
Get Started Free →Render a short MP4/GIF that takes a screenshot of a page of text (PDF screenshot, article screenshot, book scan, etc.) and animates a yellow marker-style highlight over a specific quote while blurring the surrounding text. Built on Remotion (CSS blur + mix-blend-mode multiply marker + feathered sharp reveal). Use this skill whenever the user wants to "highlight this quote in the image as a video", "make a reel that highlights this sentence", "animate a marker sweep over this passage", "blur ever
| Test case | Without → With | Effect | Δ tokens | Δ turns |
|---|---|---|---|---|
| case-08 | ✗→✓ | ▲ Improved | 11% | 0% |
| case-09 | ✗→✓ | ▲ Improved | 46% | 0% |
| case-10 | ✗→✓ | ▲ Improved | 125% | 0% |
| case-11 | ✗→✓ | ▲ Improved | 14% | 0% |
| case-12 | ✗→✓ | ▲ Improved | -10% | 0% |
Turn a screenshot of text + a target quote into a short animated MP4 where the rest of the page blurs out and a yellow marker sweeps across the quote.
The user gives you (or refers to) two things:
…and they want a short video/GIF that draws attention to that quote. Common phrasings: "highlight this sentence and make it a video", "animate a marker over this", "blur everything except…", "make me an Instagram-style highlight of this paragraph."
If the user only has a PDF, render a page to PNG first (e.g. with pdftoppm or Chrome screenshot) and then proceed.
You need three things from the user — gather them if they're missing:
| Input | Required | How to obtain | | --- | --- | --- | | Image path | yes | Ask, or use the most recent screenshot they shared | | The exact quote | yes | Copy from their message; punctuation/case do not need to be exact — OCR matching is fuzzy | | Output path | recommended | Default to the cwd as highlight_<slug>.mp4 |
Optional knobs: --duration (seconds, default 6), --blur-radius (default 10).
If OCR fails to locate the quote (e.g. handwriting, weird font, the quote spans a hyphenated line break), fall back to manual rectangles: ask the user to look at the image and give you (x, y, width, height) per line, or compute them yourself by inspecting a crop of the image. Then call render.py with --lines '[...]' instead of --quote.
The skill ships a Remotion project and two helper scripts:
text-highlight-reel/
├── SKILL.md (this file)
├── scripts/
│ ├── render.py orchestrator — call this
│ ├── find_boxes.py quote → pixel rectangles (OCR)
│ └── vision_ocr.swift macOS Vision word-box dumper
└── assets/remotion-project/ the parameterized Remotion appbashuv run "$SKILL_DIR/scripts/render.py" \ --image /abs/path/to/screenshot.png \ --quote "the sentence the user wants highlighted" \ --out /abs/path/to/output.mp4
This OCRs the image with macOS Vision, finds the quote, computes one rectangle per visible line, and renders.
Use this when OCR can't find the quote or the user wants pixel-perfect control. Inspect the image (PIL.Image.crop around suspected y-ranges, then Read the crop) to estimate (x, y, w, h) for each line of the quote. Then:
bashuv run "$SKILL_DIR/scripts/render.py" \ --image /abs/path/to/screenshot.png \ --lines '[{"x":1820,"y":365,"w":165,"h":50},{"x":40,"y":430,"w":1440,"h":50}]' \ --out /abs/path/to/output.mp4
Each line of the quote gets its own rectangle. A multi-line sentence where the first line starts mid-paragraph gets a small rect at the right end of the upper line plus a full-width rect on the next line — match what's actually visible.
The first invocation copies the Remotion project to ~/.cache/text-highlight-reel-project/ and runs npm install once (~30s, ~250MB). Subsequent renders reuse it and take seconds.
A .mp4 at the path you specified, matching the image's exact pixel dimensions (rounded to even for H.264). If the user asked for a GIF, transcode after rendering:
bashffmpeg -i output.mp4 -vf "fps=20,scale=900:-1:flags=lanczos" output.gif
To change pacing, edit assets/remotion-project/src/HighlightSweep.tsx — the schema fields blurStart, blurEnd, sweepStart, sweepEnd are all overridable via --props if you want to expose them through render.py (currently only durationSeconds and blurRadius are wired through; extend the orchestrator if needed).
The naive approach — Gaussian-blur the whole image in PIL and paste a clear crop on top — works but produces a hard rectangular boundary around the sharp region and a flat yellow rectangle that obscures the text. Three choices make this version look like a real highlighter:
filter: blur(Npx) on the <Img> rather than a pre-blurred raster. The browser samples each frame at full resolution, so the blur stays smooth at any composition size and animates continuously instead of stepping.mix-blend-mode: multiply for the yellow overlay. A solid opaque rectangle would cover the letters; multiplying yellow against the page lets the dark text show through, exactly like a real marker.OCR matching is normalized (lowercase, punctuation stripped, whitespace collapsed) and tolerates up to two mismatched words, so don't worry about getting quotation marks or curly apostrophes right. Do include enough words to be unambiguous — if the same 3-word phrase appears twice on the page, give 6–10 words so the matcher locks onto the right occurrence.
--lines.--lines.npm install — check Node ≥18; clear ~/.cache/text-highlight-reel-project/node_modules and retry.Other measured skills in the registry, with their headline benchmark lift.