Skip to content
Back to skills

Drawing And Text

ASecurity

"Draw primitives, text overlays, anchors, fonts, strokes, embedded

  • 247 stars
  • 0 votes
  • 0 copies
  • 3 views
  • Added September 8, 2026
developmentpythongobashapi

Works with

  • cli
  • api

Security analysis

A100/100

Pro scans all 5 files and shows the line behind each finding

Scanned September 8, 2026

npx -y skills add VectorSpaceLab/AREX-Skill --skill drawing-and-text --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Drawing And Text?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Drawing And Text
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/vectorspacelab-drawing-and-text/badge)](https://www.skillsdirectory.com/skills/vectorspacelab-drawing-and-text)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: drawing-and-text
description: "Draw primitives, text overlays, anchors, fonts, strokes, embedded
  color glyphs, and complex text layout on Pillow images."
disable-model-invocation: true
metadata:
  disco-role: operating
license: NOASSERTION
---

# Drawing and Text

Use this sub-skill when an agent needs to annotate or generate Pillow images with vector-like primitives, text, font metrics, anchored placement, strokes, or multilingual shaping.

## Start with the drawing context

```python
from PIL import Image, ImageDraw, ImageFont, features

im = Image.new("RGBA", (640, 360), "white")
draw = ImageDraw.Draw(im)
# For translucent overlays on RGB images, use ImageDraw.Draw(rgb_image, "RGBA").
```

- `ImageDraw.Draw(image, mode=None)` mutates the image in place.
- Coordinates use Pillow's top-left origin; drawing outside image bounds is clipped.
- Colors accept mode-appropriate tuples, integers, or color names; palette images use palette indexes unless Pillow can allocate RGB colors.
- For RGB bases with semi-transparent fills, pass `mode="RGBA"` to `ImageDraw.Draw`; for true RGBA compositing, draw on a transparent overlay and combine with `Image.alpha_composite` or `paste(..., mask=...)`.

## Draw primitives

Use `references/drawing-reference.md` for shape details. Common calls:

```python
draw.line([(20, 20), (120, 80), (220, 20)], fill="navy", width=6, joint="curve")
draw.rectangle((30, 120, 230, 210), fill=(255, 255, 0, 80), outline="black", width=3)
draw.rounded_rectangle((260, 120, 460, 210), radius=18, fill="#eef", outline="#36c", width=3)
draw.ellipse((500, 120, 600, 220), fill="tomato", outline="maroon", width=2)
draw.regular_polygon((540, 280, 48), n_sides=5, rotation=-18, fill="#ffc", outline="#960")
```

Validate bounding boxes before drawing: rectangle-like calls expect `x1 >= x0` and `y1 >= y0`; Pillow raises `ValueError` for invalid rounded rectangles and invalid regular polygon arguments.

## Load fonts safely

Use explicit TrueType/OpenType files when reproducible rendering matters:

```python
try:
    font = ImageFont.truetype("Inter-Regular.ttf", size=36)
except OSError:
    font = ImageFont.load_default(size=36)
```

- `ImageFont.truetype(font, size=10, index=0, encoding="", layout_engine=None)` needs FreeType and raises `OSError` for unreadable fonts or `ValueError` for invalid sizes.
- `ImageFont.load_default(size=...)` uses a bundled FreeType-backed default when FreeType is available; otherwise it falls back to a limited bitmap font.
- Check capabilities with `features.check_module("freetype2")` and `features.check_feature("raqm")` before relying on advanced fonts or shaping.
- See `references/text-and-fonts.md` for layout engines, measurement, anchors, and `ImageText.Text`.

## Place and validate text

Prefer anchor-based placement plus bounding-box validation over hand-tuned offsets:

```python
xy = (im.width - 24, im.height - 24)
text = "© Example"
font = ImageFont.load_default(size=24)
bbox = draw.textbbox(xy, text, font=font, anchor="rd", stroke_width=2)
if bbox[0] < 0 or bbox[1] < 0 or bbox[2] > im.width or bbox[3] > im.height:
    raise ValueError(f"text would be clipped: {bbox}")
draw.text(xy, text, font=font, anchor="rd", fill="white", stroke_width=2, stroke_fill="black")
```

- Horizontal text defaults to anchor `la`; vertical `direction="ttb"` defaults to `lt`.
- Anchor strings are two characters. Horizontal anchors commonly use `l/m/r` plus `a/t/m/s/b/d`; multiline horizontal text does not support `t` or `b` vertical anchors.
- `textbbox()` and `multiline_textbbox()` return pixel boxes `(left, top, right, bottom)`; `textlength()` returns the advance length and may differ from visible pixels because of bearings, accents, italics, or kerning.
- Use `multiline_text(..., spacing=4, align="left|center|right|justify")` for multiline placement; `text()` delegates to multiline handling when text contains newlines.

## Use complex layout only when supported

```python
layout_engine = ImageFont.Layout.RAQM if features.check_feature("raqm") else ImageFont.Layout.BASIC
font = ImageFont.truetype("NotoSans-Regular.ttf", 32, layout_engine=layout_engine)
kwargs = {"direction": "rtl", "language": "ar"} if features.check_feature("raqm") else {}
draw.text((320, 100), "English عربي", font=font, anchor="mm", fill="black", **kwargs)
```

- `direction="rtl"`, `direction="ltr"`, `direction="ttb"`, OpenType `features=[...]`, and `language="..."` require libraqm for correct shaping.
- When libraqm is unavailable, omit direction/features/language or use `ImageFont.Layout.BASIC` and document the fallback quality.
- Embedded color glyphs use `embedded_color=True` and require RGB or RGBA drawing modes; otherwise Pillow raises `ValueError`.

## Bundled helper

Run the anchor-grid helper to verify anchor behavior in the current Pillow installation:

```bash
python sub-skills/drawing-and-text/scripts/render_text_anchor_grid.py anchor-grid.png --text "Anchor"
```

The script is self-contained, uses installed Pillow only, supports `--help`, optional `--font`, `--font-size`, and validates anchor placement with `textbbox()` before saving.

## Troubleshooting

Use `references/troubleshooting.md` for failures around missing fonts, missing FreeType, missing libraqm, invalid anchors, bbox/advance confusion, alpha surprises, and embedded color mode errors.

## Boundary reminders

- Use the root `image-core` guidance for resizing, cropping, compositing strategy, and generic transforms.
- Use `formats-and-metadata` for save options, metadata, color profiles, and file-format behavior.
- Use `plugins-and-extension` for custom decoders, plugins, and format registration.

Files in this skill

  • SKILL.md5.5 KB
  • references/drawing-reference.md3.8 KB
  • references/text-and-fonts.md5.6 KB
  • references/troubleshooting.md4.8 KB
  • scripts/render_text_anchor_grid.py6.1 KB

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…