A pure Python image library made by antonio to make image generation way easier
Project description
bytecanvas
A pure Python image library made by Antonio to make image generation way easier. (zlib for DEFLATE compression, struct for binary packing).
Built for situations where installing Pillow isn't practical (constrained/sandboxed hosts, environments where compiling C extensions fails, or you just want to know exactly what's touching your image bytes) and for PNG-focused workflows that don't need the full weight of a general-purpose imaging library.
Features
- PNG decoding — 8-bit, non-interlaced PNGs across all standard color types:
- RGB
- RGBA
- Grayscale
- Grayscale + alpha
- Indexed/palette (with
tRNStransparency support) - All 5 PNG filter types (None, Sub, Up, Average, Paeth) implemented for scanline unfiltering
- PNG encoding — RGBA output, DEFLATE-compressed via stdlib
zlib - Pixel-level access —
get_pixel/set_pixelwith bounds checking - Alpha blending —
set_pixel_blendcomposites a color onto the existing pixel instead of overwriting it - Drawing primitives:
- Filled and outlined rectangles
- Lines (Bresenham's algorithm)
- Image-onto-image pasting, with optional blending
- Zero runtime dependencies — the entire library is
zlib+struct, both standard library
What's out of scope
This is a focused PNG tool, not a full replacement for every image format:
- No JPEG, GIF, BMP, or WEBP — each requires its own from-scratch codec (JPEG alone involves DCT, Huffman coding, and chroma subsampling; these are substantial standalone projects)
- No interlaced (Adam7) PNGs
- No 16-bit-per-channel PNGs
- No TrueType/OpenType font rendering (would require a font parser + bezier rasterizer)
If you need those, Pillow remains the right tool — pixelforge trades breadth for having no dependency footprint at all.
Install
pip install bytecanvas
Quick start
from bytecanvas import Image
# Create a blank canvas
img = Image(200, 100, fill=(255, 255, 255, 255))
# Draw
img.rect(10, 10, 90, 60, (255, 0, 0, 255))
img.rect(100, 20, 150, 50, (0, 200, 0, 255), filled=False) # outline only
img.line(0, 0, 199, 99, (0, 0, 255, 255))
img.set_pixel(50, 50, (0, 255, 0, 255))
img.set_pixel_blend(60, 60, (255, 0, 0, 128)) # 50% blend over whatever's there
# Save
img.save_png("output.png")
# Load an existing PNG
loaded = Image.open_png("output.png")
print(loaded.get_pixel(50, 50))
print(loaded.width, loaded.height)
API reference
Image(width, height, fill=(0, 0, 0, 0))
Creates a new RGBA image. fill is a 4-tuple, defaults to fully transparent black.
Image.open_png(path) / Image.from_png_bytes(raw_bytes)
Class methods that decode a PNG from disk or from raw bytes, returning an Image.
.save_png(path, compress_level=6) / .to_png_bytes(compress_level=6)
Encodes the image as PNG, to disk or as bytes. compress_level is passed straight to zlib (0–9).
.get_pixel(x, y) → (r, g, b, a)
Raises PFError if out of bounds.
.set_pixel(x, y, color)
Overwrites a pixel. color can be a 3-tuple (alpha assumed 255) or 4-tuple.
.set_pixel_blend(x, y, color)
Alpha-composites color onto the existing pixel. Silently no-ops if out of bounds (safe for drawing near edges).
.fill(color)
Fills the entire image with one color.
.rect(x0, y0, x1, y1, color, filled=True)
Draws a rectangle. Coordinates are clamped to image bounds and auto-sorted (so x0 > x1 is fine).
.line(x0, y0, x1, y1, color)
Bresenham line, blended.
.paste(other_image, x, y, blend=True)
Pastes another Image onto this one at (x, y). Clips automatically at edges.
.copy()
Returns a deep copy.
Correctness
The PNG decoder and encoder have been cross-validated against Pillow-generated reference files (not just tested against pixelforge's own output) across RGBA, RGB, grayscale, and palette color modes, with zero pixel-level discrepancies. Round-trip encode→decode is pixel-exact.
License
MIT
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file bytecanvas-1.6.3.tar.gz.
File metadata
- Download URL: bytecanvas-1.6.3.tar.gz
- Upload date:
- Size: 6.4 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
7b6c68c79d3c4c19bda5b4cd7220adad677e34081f5e93232e9316083c6b323e
|
|
| MD5 |
e4415c544b078b680a72e7acc5506252
|
|
| BLAKE2b-256 |
3b59868bc4fedacb837e43e73ea9479abb0e60e8eff8ed7512bb59816426495f
|
File details
Details for the file bytecanvas-1.6.3-py3-none-any.whl.
File metadata
- Download URL: bytecanvas-1.6.3-py3-none-any.whl
- Upload date:
- Size: 7.0 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
2bbe548bb99241eff0df91c41403a9f863c70eb3627e8db290396f8fb954be65
|
|
| MD5 |
89f0b07120ba08a1a0d64ac736661b9f
|
|
| BLAKE2b-256 |
9503da860468afd9e7c901ccfc0870b680ab8c76b71808a471c5393d8944e0d7
|