Skip to content
Back to skills

Drawing And Text

ASecurity

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

  • 247 stars
  • 0 votes
  • 0 copies
  • 11 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…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.