ImageMagick Bug Note: Stroke State Persists Across Annotate Calls
Discovered: 2026-04-10
Fixed in: instagram-carousel-generate.sh
Symptom: Text appearing with visible outlines in rendered carousel slides
What Happened
Section titled “What Happened”The carousel preview showed text with outlines (a “stroked” appearance) on several slides. The affected slides were 1, 3, 4, 5, 6, and 7. Slide 2 had no issue.
Root Cause
Section titled “Root Cause”In ImageMagick, drawing properties like -stroke and -strokewidth are global state within a single magick command. Once set, they apply to every subsequent operation — including -annotate (text) commands — until explicitly reset.
The shell script used a pattern like this to draw decorative divider lines:
-stroke "${DARK}" -strokewidth 1.5 -fill none \-draw "line 390,660 690,660" \-fill "${SEC}" -font "${JOST}" -pointsize 28 \-annotate +0+60 "Some text here"The -fill "${SEC}" call updates the fill color, but it does not reset the stroke. The -annotate command that follows therefore renders the text with both a fill and a stroke — producing a visible outline around each character.
Why It Was Hard to Spot
Section titled “Why It Was Hard to Spot”The stroke color was ${DARK} (#1A1A1A) applied on top of dark text, so the outline appeared as a subtle thickening rather than an obvious colored border. It was only noticeable when viewing the rendered JPG at full resolution.
Add -stroke none -strokewidth 0 immediately after every -draw "line..." call, before the next -annotate:
-stroke "${DARK}" -strokewidth 1.5 -fill none \-draw "line 390,660 690,660" \-stroke none -strokewidth 0 \ ← reset here-fill "${SEC}" -font "${JOST}" -pointsize 28 \-annotate +0+60 "Some text here"Eight resets were added across slides 1, 3 (×2), 4 (×2), 5, 6, and 7.
General Rule for ImageMagick Scripts
Section titled “General Rule for ImageMagick Scripts”Always reset -stroke none -strokewidth 0 after any -draw that uses a stroke, before the next text annotation. This applies even when you reassign -fill — fill and stroke are independent state variables.
Other properties that carry state across operations and may need explicit resets:
| Property | Reset with |
|---|---|
| Stroke color | -stroke none |
| Stroke width | -strokewidth 0 |
| Fill color | -fill <new-color> |
| Font | -font <new-font> |
| Point size | -pointsize <n> |
| Gravity | -gravity <direction> |
Related
Section titled “Related”- instagram-carousel-generate.sh — the fixed script
- — campaign folder