

This project is part of the
@thi.ng/umbrella monorepo.
About
Typed array backed, packed integer and unpacked floating point pixel buffers w/ customizable formats, blitting, dithering, conversions.

- Buffer creation from HTML image elements w/ opt resize & format
conversion (browser only)
- Buffer-to-buffer blitting w/ automatic format conversion
- Buffer-to-canvas blitting
- Buffer-to-buffer blending w/ Porter-Duff
operators
- Pre/post-multiply alpha
- Region / sub-image extraction
- Single-channel manipulation / extraction / replacement / conversion
- Inversion
- XY pixel accessors
- 10 packed integer and 4 floating point preset formats (see table
below)
- Ordered dithering w/ customizable Bayer matrix size and target color
steps (int formats only)
- Declarative custom format & optimized code generation
- HTML canvas creation &
ImageData
utilities
WIP features
Packed integer pixel formats
All packed integer formats use the canvas native ABGR 32bit format as
common intermediate for conversions. During conversion to ABGR, channels
with sizes smaller than 8 bits will be scaled appropriately to ensure an
as full-range and as linear as possible mapping. E.g. a 4 bit channel
will be scaled by 255 / 15 = 17.
Format specs can freely control channel layout within current limits:
- Channel sizes: 1 - 32 bits.
- Storage: 8, 16 or 32 bits per pixel
New formats can be defined via defPackedFormat()
.
Format ID | Bits per pixel | Description |
---|
ALPHA8 | 8 | 8 bit channel (alpha only) |
GRAY8 | 8 | 8 bit single channel (grayscale conv) |
GRAY_ALPHA8 | 16 | 8 bit single channel (grayscale conv), 8 bit alpha |
GRAY16 | 16 | 16 bit single channel (grayscale conv) |
GRAY_ALPHA16 | 32 | 16 bit single channel (grayscale conv), 16 bit alpha |
ARGB4444 | 16 | 4 channels @ 4 bits each |
ARGB1555 | 16 | 5 bits each for RGB, 1 bit alpha |
RGB565 | 16 | 5 bits red, 6 bits green, 5 bits blue |
RGB888 | 32 (24 effective) | 3 channels @ 8 bits each |
ARGB8888 | 32 | 4 channels @ 8 bits each |
BGR888 | 32 (24 effective) | 3 channels @ 8 bits each |
ABGR8888 | 32 | 4 channels @ 8 bits each |
ALPHA8
is mapped from/to ABGR alpha channelGRAY8/16
, GRAY_ALPHA8/16
compute grayscale/luminance when
converting from ABGR and in return produce grayscale ABGR- In all built-in formats supporting it, the alpha channel always
occupies the most-significant bits (up to format size)
Floating point pixel formats
Strided floating point format presets for use with floatBuffer()
. New
formats can be defined via defFloatFormat()
.
Format ID | Channel count | Description |
---|
FLOAT_GRAY | 1 | Single channel / grayscale |
FLOAT_GRAY_ALPHA | 2 | Grayscale and alpha channel |
FLOAT_RGB | 3 | Red, Green, Blue |
FLOAT_RGBA | 4 | Red, Green, Blue, Alpha |
- All color channels are unclamped (but can be clamped via
buf.clamp()
). For conversion to packed int formats assumed to
contain normalized data (i.e. [0..1] interval) - Conversion between float formats is currently unsupported
Status
STABLE - used in production
Related packages
Installation
yarn add @thi.ng/pixel
// ES module
<script type="module" src="https://unpkg.com/@thi.ng/pixel?module" crossorigin></script>
// UMD
<script src="https://unpkg.com/@thi.ng/pixel/lib/index.umd.js" crossorigin></script>
Package sizes (gzipped, pre-treeshake): ESM: 4.70 KB / CJS: 4.88 KB / UMD: 4.79 KB
Dependencies
Usage examples
Several demos in this repo's
/examples
directory are using this package.
A selection:
Screenshot | Description | Live demo | Source |
---|
 | Interactive image processing (adaptive threshold) | Demo | Source |
 | Pixel buffer manipulations | Demo | Source |
 | Port-Duff image compositing / alpha blending | Demo | Source |
 | Fork-join worker-based raymarch renderer | Demo | Source |
| Minimal multi-pass / GPGPU example | Demo | Source |
API
Generated API docs
import * as pix from "@thi.ng/pixel";
import { SRC_OVER_I } from "@thi.ng/porter-duff";
import IMG from "../assets/haystack.jpg";
import LOGO from "../assets/logo-64.png";
Promise
.all([IMG, LOGO].map(pix.imagePromise))
.then(([img, logo]) => {
const buf = pix.PackedBuffer.fromImage(img, pix.RGB565, 256, 256);
pix.PackedBuffer.fromImage(logo, pix.GRAY_ALPHA88)
.premultiply()
.blend(SRC_OVER_I, buf, {
dx: 10,
dy: 10
});
const region = buf.getRegion(32, 96, 128, 64);
region.blit(buf, { dx: 96, dy: 32 });
const ctx = pix.canvas2d(buf.width, buf.height * 3);
buf.blitCanvas(ctx.canvas);
const id = 0;
const ch = buf.getChannel(id).invert();
for (let y = 0; y < ch.height; y += 2) {
for (let x = (y >> 1) & 1; x < ch.width; x += 2) {
ch.setAt(x, y, 0xff);
}
}
buf.setChannel(id, ch);
buf.blitCanvas(ctx.canvas, 0, buf.height);
buf.as(GRAY8).blitCanvas(ctx.canvas, 0, buf.height * 2);
document.body.appendChild(ctx.canvas);
});
TODO see examples & source comments for now
Authors
Karsten Schmidt
License
© 2019 - 2020 Karsten Schmidt // Apache Software License 2.0