Metadata-Version: 2.4
Name: bytecanvas
Version: 1.6.3
Summary: A pure Python image library made by antonio to make image generation way easier
Requires-Python: >=3.9
Description-Content-Type: text/markdown

# 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 `tRNS` transparency 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_pixel` with bounds checking
- **Alpha blending** — `set_pixel_blend` composites 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

```bash
pip install bytecanvas
```

## Quick start

```python
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
