Skip to main content

pydrawcv

An editable, retained-mode 2D drawing library built on NumPy and OpenCV. Create illustrations, procedural graphics, diagrams, freehand strokes, and animation as scene objects; render pixels whenever you need them.

Install pydrawcv; import drawcv. Requires Python 3.12 or newer.

pip install pydrawcv

For local development:

pip install -e ".[dev,typography]"
python -m pytest -q

What's new in 0.10.0

Version 0.10.0 is a major feature release adding extensive vector-geometry tools, stroke spaces, and vector styling:

  • Screen-space and object-space strokes: StrokeStyle(space="screen") keeps line widths and dashes constant in screen pixels, while StrokeStyle(space="object") scales and shears with affine transforms.
  • Curve-preserving shape-to-path conversion: shape.to_path() converts circles, ellipses, rounded rectangles, and arcs into editable Path objects preserving exact elliptical curves.
  • Stroke-to-path outlining: shape.stroke_to_path(tolerance=0.25) turns solid and dashed strokes—including pressure/velocity freehand ribbons—into filled vector outlines ready for editing, boolean operations, and SVG export.
  • Path measurement & curve queries: path.length(), path.point_at(progress), and path.tangent_at(progress) query arc-length positions and tangent unit vectors.
  • Curve-preserving trimming & splitting: path.trim(start, end) and path.split_at(progress) extract segments along semantic curves without polygon flattening.
  • Filled-region offsets: path.offset(distance, join_style=...) expands or contracts closed regions with round, bevel, or miter joins, correctly handling holes.
  • Reusable path markers: Marker(artwork, ...) attaches reusable vector artwork to path.marker_start, marker_mid, and marker_end with auto-tangent orientation.
  • Editable vector patterns: VectorPattern(artwork, width, height, ...) provides live tileable vector pattern fills and strokes with native SVG <pattern> export.
  • Editable alpha & luminance vector masks: VectorMask(artwork, bounds, mode=...) enables soft fades and vector masks with native SVG <mask /> export.
  • Rendering & SVG fidelity fixes: Nonzero fills, clipping, root SVG attributes, transformed text clipping, and strict paint-order diagnostics.

See the complete 0.10.0 Release Notes for full API examples and compatibility contracts.

Draw and export an image

from drawcv import (
    Scene, OpenCVRenderer, Line, Circle, Point, Color,
    StrokeStyle, FillStyle, CapStyle,
)

scene = Scene(640, 360, background=Color.white())
node = Circle(center=Point(100, 180), radius=35,
              fill=FillStyle(color=Color(50, 140, 200)))
connection = Line(
    start=Point(150, 180), end=Point(560, 180),
    stroke=StrokeStyle(color=Color(30, 60, 90), width=8,
                       cap_style=CapStyle.BUTT, dash_array=(20, 12)),
)
scene.add(node)
scene.add(connection)
renderer = OpenCVRenderer()
renderer.render(scene).save("diagram.png")

The scene remains editable after export. Canvas.buffer is a uint8 BGR array; Canvas.to_numpy() returns a copy. For transparent PNG output, set a transparent scene background and explicitly request BGRA:

scene.background = Color(0, 0, 0, 0)
transparent = renderer.render(scene, alpha=True)
transparent.save("diagram-transparent.png")
transparent.flatten(Color.white()).save("diagram-white.jpg")

See transparent output and alpha semantics.

Edit, undo, and save the scene

with scene.edit(connection, name="Restyle connection"):
    connection.stroke.width = 12
    connection.stroke.dash_offset = 8

scene.undo()
scene.redo()
assert scene.get(connection.id) is connection

scene.save_json("diagram.drawcv.json")
loaded = Scene.load_json("diagram.drawcv.json")
renderer.render(loaded).save("diagram-loaded.png")

Style and transform assignments reject invalid values without corrupting existing state. Use scene.edit for compound changes and geometry edits, and scene.batch for multiple recorded commands. See reliable edits for rollback guarantees and the limits of raw attribute/list mutation.

New scenes use schema 1.13, including vector masks, vector patterns, reusable path markers, retained text runs, path clips, paints, and effects. Schemas 1.0 through 1.12 load with compatible defaults. Older readers reject 1.13; update readers before sharing new documents with them.

Organize and position objects

Use Group(children=[...]) for transform hierarchies and scene.create_layer(name) plus scene.add(obj, layer=name) for rendering layers. Use scene.select([...]) for collective transforms and scene.find_by_name/tag/type for lookup. Objects have stable IDs, visibility, opacity, z-order, tags, and metadata.

from drawcv import place_right_of

with scene.edit(connection):
    place_right_of(connection, node, gap=20, align="center")

Coordinates start at the top left; x increases rightward, y downward, and positive rotation is clockwise. Local geometry maps through object and ancestor transforms. Stroke widths and dashes stay in screen pixels by default. Set StrokeStyle(space="object") for widths, dashes, caps, and joins that transform with the object. See stroke spaces. Colors are authored as RGB integers 0–255 with alpha 0–1; OpenCV buffers use BGR. Alpha compositing uses source-over with premultiplied internal surfaces for isolation.

Animate a drawing

from drawcv import Timing

connection.timing = Timing(duration=2)
scene.animate(connection, "stroke.dash_offset", 0, 32, duration=2)
scene.render_at_time(0.75).save("frame.png")

render_at_time restores authored state and does not add history entries. scene.sample(t) deliberately updates the live model. VideoRenderer provides frame iteration, image-sequence export, and video export through OpenCV codecs. Line, Polyline, Arrow, BezierCurve, Path, FreehandStroke, and Arc support progressive reveal. See stroke/progress semantics for closure, transforms, phase anchoring, and the different progress parameterizations.

Examples and reference

Caps, joins, dashes, and pressure strokes

Run examples as modules from the repository root:

python -m examples.stroke_styles
python -m examples.progressive_drawing
python -m examples.transparent_output

Capabilities and current limits

Area Available Limits / next work
Geometry Lines, polygons, circles/ellipses, arcs, rectangles, arrows, quadratic/cubic curves, compound paths, vector booleans (union, intersection, difference, XOR) Curves rasterize as approximations during OpenCV rendering
Strokes Butt/round/square caps, round/bevel/miter joins, miter limits, dashed and variable-width outlines Screen/object stroke spaces; arrowhead outlines stay solid
Paint Solid, linear/radial/conic gradients, gradient strokes, RGBA stops, repeat/reflect spread, image tiles, editable vector patterns, fill rules, blend modes Nested vector patterns inside pattern artwork remain unsupported
Freehand Raw editable samples; pressure/velocity widths; simplification, smoothing, interpolation No textured brush system
Scene Groups, layers, lookup, selection, relative positioning, affine transforms Bounds may be conservative; hit testing is geometric and can select dash gaps
Compositing Opt-in straight BGRA/PNG output; premultiplied images, raster masks, editable alpha/luminance vector masks, blur, shadows, isolated opacity, blend modes, raster effects Alpha export currently PNG only
Typography Hershey compatibility; optional TTF/OTF, Latin/Thai/Arabic shaping, ICU bidi, explicit fallback, wrapping and metrics Other scripts, emoji, advanced format controls and glyph strokes remain unsupported
Persistence JSON 1.13; forward migration; cloning; undo/redo Direct edits require transaction discipline; older readers need updating
Animation Timing, easing, numeric/value tracks, progressive drawing, video No built-in enum/dash-array interpolation; codec availability varies
Interchange Native retained SVG import & export with text interchange and reported PNG fallbacks; raster images, editable JSON, video PDF export remains future work
Performance Profiled benchmarks; coverage-region blending/gradients; cheaper transform resolution Full-canvas masks/effect surfaces remain; no dirty-region redraw

Metadata

Release files for pydrawcv 0.10.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for pydrawcv 0.10.0
File Size Uploaded
pydrawcv-0.10.0.tar.gz 2.5 MB Details

Built distribution (wheel)

Table of built distributions (wheels) for pydrawcv 0.10.0
File Interpreter ABI Platform
pydrawcv-0.10.0-py3-none-any.whl Python 3 none any Details

Total release size: 2.8 MB

Release files / pydrawcv-0.10.0.tar.gz

Download URL pydrawcv-0.10.0.tar.gz
Size 2.5 MB
Tags Source
SHA-256 checksum
How to use checksums
65a7c8501868690f8604afd564e0b0d890b1a3409e21491ab93197497f8be5e3
BLAKE2b-256 checksum
How to use checksums
0f8a3858ad08d3af27ee2a633769c1f6a9116e7e697472ddf7e5b50633fbb683
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.12.2

Release files / pydrawcv-0.10.0-py3-none-any.whl

Download URL pydrawcv-0.10.0-py3-none-any.whl
Size 274.9 kB
Tags Python 3
SHA-256 checksum
How to use checksums
a9c8d3899a00a95e31e1a2d41d818677f5794ef4f1ce5799aafdc35c4135f61d
BLAKE2b-256 checksum
How to use checksums
324dddbbe95f617cc90987fbb97cda64e5ca21b9bf6b1224ccae8c7b93fef22d
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.12.2

Release history Release notifications | RSS feed

0.11.0

2 release files

This release

0.10.0 This release

2 release files

0.9.1

2 release files

0.9.0

2 release files

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page