Skip to content

Latest commit

 

History

History

Folders and files

NameName
Last commit message
Last commit date

parent directory

..
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

README.md

Zignal Python Bindings

PyPI version Python versions Downloads License: MIT

Zero-dependency image processing primitives written in Zig and packaged for Python.

Feature Overview

Area Highlights
Images PNG/JPEG load/save, resize & warp, crop/letterbox, insert/extract, Gaussian/median filters, motion blur
Pixels & Arrays Direct indexing/assignment, slice updates, zero-copy NumPy interop both directions
Colors 12 color models (Rgb/Rgba, Hsl/Hsv, Lab/Lch, Xyz/Xyb, Oklab/Oklch, Lms, Ycbcr) with automatic conversion
Canvas & Fonts Lines, arcs, splines, polygons, flood fills, bitmap font text rendering
Geometry Rectangle algebra, convex hulls, similarity/affine/projective transforms
Terminal Output SGR, Braille, Sixel, and Kitty renderers with automatic format negotiation
Numerics Matrices with rich linear algebra, PCA, optimization (Hungarian assignment + MaxLIPO+TR global optimizer), running statistics
QR Codes Encode text/bytes to QR images and decode them back, including from photos (perspective, uneven lighting, rotation)

All functionality is implemented in Zig with no runtime dependencies, making the wheel lightweight and easy to vendor.

Installation

pip install zignal-processing
  • Python 3.10 – 3.14 (CPython)
  • Prebuilt wheels ship for:
    • Linux (manylinux2014) x86_64, aarch64
    • macOS x86_64 and arm64
    • Windows x86_64
  • Building from source requires Zig 0.15.0 or newer available on your PATH.

If CPython headers/libraries are in a non-standard location, set PYTHON_INCLUDE_DIR, PYTHON_LIBS_DIR, and PYTHON_LIB_NAME before installing.

Quickstart

import numpy as np
import zignal

# Load or create an image
img = zignal.Image.load("photo.jpg")                 # PNG/JPEG
canvas = zignal.Image(480, 640, color=zignal.Rgb(30, 144, 255)).canvas()

# Draw & process
canvas.draw_circle((120, 160), 60, zignal.Rgba(255, 255, 255, 180), fill=True)
img = img.gaussian_blur(1.5)
img = img.resize(0.5, zignal.Interpolation.BILINEAR)

# Pixels + NumPy (shared memory views)
img[10, 20] = zignal.Hsv(60, 100, 100)
np_view = img.to_numpy()                   # (rows, cols, 3) uint8 view
np_view[..., 0] = np.clip(np_view[..., 0] + 32, 0, 255)  # modifies img in-place
img2 = zignal.Image.from_numpy(np_view)    # zero-copy back into Zig

# Streaming stats & procedural noise
stats = zignal.RunningStats()
for value in np_view.mean(axis=-1).flat:
    stats.add(float(value))
noise = zignal.perlin(0.2, 0.4, amplitude=1.2, frequency=2.5, octaves=4)
print(f"μ={stats.mean:.3f} σ={stats.std_dev:.3f} perlin={noise:.3f}")

# Terminal preview (auto: kitty → iterm2 → sixel → sgr fallback)
print(f"{img:auto}")

# Save
img.save("out.png")

Documentation & Support

Development

zig build python-bindings          # build extension + stubs
cd bindings/python
uv venv && uv pip install -e .     # editable install
uv run pytest -q                   # run tests

Building Wheels

To build a wheel for your current platform:

cd bindings/python
uv run python -m build --wheel

To cross-compile or specify optimization:

ZIG_TARGET=x86_64-linux-gnu ZIG_OPTIMIZE=ReleaseFast uv run python -m build --wheel

Environment Variables

Variable Description Default
ZIG_TARGET Zig target triple native
ZIG_OPTIMIZE Optimization mode (Debug, ReleaseSafe, ReleaseFast, ReleaseSmall) ReleaseFast
ZIG_CPU CPU micro-architecture (e.g., baseline, x86_64_v3) baseline

For portable Linux wheels, it is recommended to run auditwheel repair on the resulting wheel. On macOS, use delocate-wheel.

Contributing Bindings

Follow the bindings guide for argument parsing helpers, enum registration, image ownership, and stub generation.

Sponsors

Special thanks to B Factory, Inc, the Founding Sponsor of Zignal. They originally developed this library and graciously transferred ownership to the community to ensure its long-term maintenance and growth.

License

MIT