Skip to content

BaseMax/image-pixel-nodejs

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

8 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

image-pixel-nodejs

A minimal, clean, and efficient Node.js pipeline to generate images (PNG, BMP, JPEG, WebP) from raw pixel data.

Supports Base64, raw binary, and streaming input β€” with a built-in REST API.


✨ Features

  • Multiple input formats: Base64 CSV, raw binary buffer, or readable stream
  • Multiple output formats: PNG, BMP, JPEG, WebP (any combination)
  • Streaming parser for large pixel datasets (low memory)
  • Binary input path β€” no CSV/Base64 overhead, fastest ingestion
  • REST API (Express) with JSON, binary, and streaming endpoints
  • WASM encoder β€” uses @img/sharp-wasm32 when available, falls back to native sharp
  • All encodings run in parallel via Promise.all
  • Clean, DRY, and composable architecture

πŸ“¦ Installation

git clone https://github.com/BaseMax/image-pixel-nodejs.git
cd image-pixel-nodejs
npm install

Optional β€” true WebAssembly encoder (no native bindings required):

npm install @img/sharp-wasm32

πŸš€ Usage

CLI demo (all features)

node app.js

REST API server

node src/server.js
# or
npm run server

πŸ“₯ Input Formats

1. Base64 (original)

Base64-encoded comma-separated RGB values:
"255,0,0, 0,255,0, 0,0,255, 255,255,0"

2. Binary (fastest)

Raw RGB bytes β€” 3 bytes per pixel, no encoding overhead.

const binary = Buffer.from([255, 0, 0,   0, 255, 0,   0, 0, 255,   255, 255, 0]);

3. Stream (low-memory)

Any Readable that emits comma-separated RGB integers. The parser reassembles tokens split across chunk boundaries.


βš™οΈ Pipeline API

generate(options) β€” src/pipeline.js

const { generate } = require("./src/pipeline");

const result = await generate({
  base64,           // string  β€” Base64-encoded CSV pixels
  // binary,        // Buffer  β€” raw RGB bytes  (pick one of the three)
  // stream,        // Readable β€” CSV stream
  width:  2,
  height: 2,
  formats: ["png", "bmp", "jpeg", "webp"],  // any subset
  writeFiles: true,          // save files to outputDir (default: false)
  outputDir: ".",            // where to save (default: ".")
  encodeOptions: {
    jpeg: { quality: 90, progressive: false },
    webp: { quality: 80, lossless: false }
  }
});

Returns

{
  png:  string,   // Base64 (if requested)
  bmp:  string,
  jpeg: string,
  webp: string,
  buffers: {
    png:  Buffer,
    bmp:  Buffer,
    jpeg: Buffer,
    webp: Buffer,
  }
}

🌐 REST API

Start the server:

node src/server.js        # default port 3000
PORT=8080 node src/server.js

GET /health

{ "status": "ok", "version": "2.0.0" }

POST /generate β€” Base64 JSON input

curl -X POST http://localhost:3000/generate \
  -H "Content-Type: application/json" \
  -d '{
    "base64": "MjU1LDAsMCwgMCwyNTUsMCwgMCwwLDI1NSwgMjU1LDI1NSww",
    "width": 2,
    "height": 2,
    "formats": ["png", "jpeg", "webp"],
    "encodeOptions": { "jpeg": { "quality": 85 } }
  }'

POST /generate/binary β€” Raw RGB bytes

curl -X POST \
  "http://localhost:3000/generate/binary?width=2&height=2&formats=png,jpeg" \
  -H "Content-Type: application/octet-stream" \
  --data-binary $'\xff\x00\x00\x00\xff\x00\x00\x00\xff\xff\xff\x00'

POST /generate/stream β€” Streaming CSV pixels

echo "255,0,0, 0,255,0, 0,0,255, 255,255,0" | \
  curl -X POST \
    "http://localhost:3000/generate/stream?width=2&height=2&formats=png,bmp" \
    -H "Content-Type: text/plain" \
    --data-binary @-

πŸ”© WASM Encoder

src/encoders/wasmEncoder.js resolves the encoder at startup:

  1. @img/sharp-wasm32 β€” true WebAssembly build (no native addons, works in restricted environments)
  2. sharp β€” native libvips build (fallback)
const { wasmEncode, wasmBackend } = require("./src/encoders/wasmEncoder");

console.log(wasmBackend); // "wasm32" or "native"

const png  = await wasmEncode(rgbaBuffer, width, height, "png");
const jpeg = await wasmEncode(rgbaBuffer, width, height, "jpeg", { quality: 90 });
const webp = await wasmEncode(rgbaBuffer, width, height, "webp", { lossless: true });

πŸ“ Constraint

pixels.length === width Γ— height Γ— 3   (for base64 / stream inputs)
buffer.length === width Γ— height Γ— 3   (for binary input)

🧠 Pipeline

Input (base64 / binary / stream)
  ↓
Parse & validate
  ↓
RGB β†’ RGBA
  ↓
Parallel encode β†’ PNG + BMP + JPEG + WebP
  ↓
(Optional) save to disk
  ↓
Return { base64 strings + raw Buffers }

πŸ“ Project Structure

.
β”œβ”€β”€ app.js                     CLI demo (all features)
β”œβ”€β”€ src/
β”‚   β”œβ”€β”€ pipeline.js            Core generate() function
β”‚   β”œβ”€β”€ server.js              Express REST API
β”‚   β”œβ”€β”€ parsers/
β”‚   β”‚   β”œβ”€β”€ base64Parser.js    Base64 β†’ pixel array
β”‚   β”‚   β”œβ”€β”€ binaryParser.js    Raw Buffer β†’ RGBA
β”‚   β”‚   └── streamingParser.js Transform stream for CSV pixels
β”‚   └── encoders/
β”‚       β”œβ”€β”€ pngEncoder.js      pngjs
β”‚       β”œβ”€β”€ bmpEncoder.js      bmp-js
β”‚       β”œβ”€β”€ jpegEncoder.js     sharp (JPEG)
β”‚       β”œβ”€β”€ webpEncoder.js     sharp (WebP)
β”‚       └── wasmEncoder.js     @img/sharp-wasm32 β†’ sharp fallback
β”œβ”€β”€ package.json
└── README.md

⚑ Performance Notes

Input Overhead Best for
binary none server-to-server calls
base64 decode + CSV general use
stream chunked CSV large images
Encoder Backend Formats
pngEncoder pngjs (pure JS) PNG
bmpEncoder bmp-js (pure JS) BMP
jpegEncoder sharp / libvips JPEG
webpEncoder sharp / libvips WebP
wasmEncoder sharp-wasm32 PNG, JPEG, WebP

⭐ Contributing

Pull requests are welcome. For major changes, please open an issue first.


πŸ“œ License

GPL-3.0 License

Copyright (c) 2026 Seyyed Ali Mohammadiyeh (Max Base)

About

A minimal, clean, and efficient Node.js pipeline to generate images (PNG and BMP) from raw pixel data. This project converts a Base64-encoded pixel buffer into an image, saves it, and returns Base64-encoded outputs.

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors