bytecanvas
v1.6.3
Published
A pure Node.js image library with zero third-party dependencies — PNG encode/decode and drawing primitives using only built-ins
Maintainers
Readme
bytecanvas
A pure Node.js image library made by Antonio with zero third-party dependencies. Uses only Node.js built-ins (zlib for DEFLATE compression, Buffer for binary packing).
Built for situations where installing heavy image libraries isn't practical — constrained environments, minimal Docker images, serverless functions, or any place you want to know exactly what's touching your image bytes.
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)
- PNG encoding — RGBA output, DEFLATE-compressed via built-in
zlib - Pixel-level access —
getPixel/setPixelwith bounds checking - Alpha blending —
setPixelBlendcomposites a color onto the existing pixel - Drawing primitives:
- Filled and outlined rectangles
- Lines (Bresenham's algorithm)
- Image-onto-image pasting, with optional blending
- Zero runtime dependencies —
zlib,Buffer, andfsare all Node.js built-ins
What's out of scope
- No JPEG, GIF, BMP, or WEBP
- No interlaced (Adam7) PNGs
- No 16-bit-per-channel PNGs
Install
npm install bytecanvasQuick start
const { Image } = require('bytecanvas');
// Create a blank canvas
const img = new Image(200, 100, [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], false); // outline only
img.line(0, 0, 199, 99, [0, 0, 255, 255]);
img.setPixel(50, 50, [0, 255, 0, 255]);
img.setPixelBlend(60, 60, [255, 0, 0, 128]); // 50% blend
// Save
img.savePng('output.png');
// Load an existing PNG
const loaded = Image.openPng('output.png');
console.log(loaded.getPixel(50, 50)); // [0, 255, 0, 255]
console.log(loaded.width, loaded.height); // 200 100API reference
new Image(width, height, fill?)
Creates a new RGBA image. fill is a [r, g, b, a] array, defaults to [0, 0, 0, 0] (fully transparent black).
Image.openPng(path) → Image
Decode a PNG from disk.
Image.fromPngBytes(buffer) → Image
Decode a PNG from a Buffer or Uint8Array.
.savePng(path, compressLevel?)
Save the image as a PNG file. compressLevel is 0–9 (default 6).
.toPngBytes(compressLevel?) → Buffer
Encode the image as PNG bytes without writing to disk.
.getPixel(x, y) → [r, g, b, a]
Returns the RGBA value of a pixel. Throws BCError if out of bounds.
.setPixel(x, y, color)
Overwrites a pixel. color can be [r, g, b] (alpha assumed 255) or [r, g, b, a].
.setPixelBlend(x, y, color)
Alpha-composites color onto the existing pixel. Silently no-ops if out of bounds.
.fill(color)
Fills the entire image with one color.
.rect(x0, y0, x1, y1, color, filled?)
Draws a rectangle. Coordinates are clamped and auto-sorted. filled defaults to true.
.line(x0, y0, x1, y1, color)
Bresenham line, blended.
.paste(otherImage, x, y, blend?)
Pastes another Image onto this one at (x, y). Clips at edges. blend defaults to true.
.copy() → Image
Returns a deep copy.
Errors
BCError— base error class for all bytecanvas errorsUnsupportedPNGError— thrown when a PNG feature outside this module's scope is encountered
const { Image, BCError, UnsupportedPNGError } = require('bytecanvas');Publishing (from shell)
cd bytecanvas
npm login # one-time: enter your npm credentials
npm publishLicense
MIT
