@faceless-photolib/image-codec
Node image decode/encode (PNG/JPEG/WebP/AVIF via sharp) and an SVG-backed TextRasterizer — the ImageCodec / AssetStore boundary adapters for the faceless-photolib engine.
Node boundary adapters for faceless-photolib — a headless, color-managed, GPU-accelerated image-editing engine.
This package implements the engine's I/O ports with sharp:
an ImageCodec that decodes PNG/JPEG/WebP/AVIF bytes into a straight-alpha f32 RGBA buffer
(never an 8-bit intermediate) carrying an explicit, inspectable color-space tag, and encodes float
buffers back to PNG/JPEG/TIFF; an in-memory AssetStore for content-addressed (SHA-256) asset
bytes; and a TextRasterizer that renders a text spec via SVG. sharp is a dependency of this
package only — the engine core never imports it.
Install
pnpm add @faceless-photolib/image-codecUsage
import {
createNodeImageCodec,
createInMemoryAssetStore,
createNodeTextRasterizer,
} from "@faceless-photolib/image-codec";
const codec = createNodeImageCodec();
const store = createInMemoryAssetStore();
// Decode → a Result<DecodedImage>; narrow the union, never assume success.
const decoded = await codec.decode(encodedBytes);
if (decoded.kind === "ok") {
const { width, height, pixels, colorSpaceTag } = decoded.value;
console.log(`${width}×${height}, ${colorSpaceTag.kind}, ${pixels.length} f32 samples`);
// Re-encode the float buffer to a concrete output format.
const out = await codec.encode(decoded.value, { kind: "png", bitDepth: 16 });
if (out.kind === "ok") {
const hash = await store.put(out.value); // Result<ContentHash>
console.log("stored", hash.kind === "ok" ? hash.value : hash.kind);
}
}
// Rasterize text via SVG (outside the cross-backend pixel-parity guarantee).
const rasterizer = createNodeTextRasterizer();
const text = await rasterizer.rasterizeText(spec);API
| Export | Description |
|---|---|
createNodeImageCodec() | Creates the sharp-backed ImageCodec (decode PNG/JPEG/WebP/AVIF, encode PNG/JPEG/TIFF). |
createInMemoryAssetStore() | Creates an in-memory AssetStore, content-addressed by SHA-256 hex of the bytes. |
createNodeTextRasterizer() | Creates the sharp/librsvg-backed TextRasterizer port adapter. |
ImageCodec | Port interface: decode(bytes) / encode(image, target), each returning a Result. |
AssetStore | Port interface: resolve(hash) / put(bytes) / has(hash). |
DecodedImage | A decoded straight-RGBA Float32Array image with width, height, and a colorSpaceTag. |
EncodeTarget | Discriminated union of output targets: png / jpeg / exr / tiff. |
ColorSpaceTag | Always-present color-space tag (srgb, display-p3, unknown-tagged with raw ICC, …). |
Every boundary method returns a Result<T> (@faceless-photolib/schemas) — unsupported formats,
corrupt bytes, missing assets, and unimplemented targets (e.g. EXR encode) surface as explicit
not-implemented / invalid-request / not-found values rather than throwing or returning blanks.
License
MIT
API reference
8 public exports · 8 documented · generated from source.
createInMemoryAssetStorefunctioncreateInMemoryAssetStore(): AssetStoreCreate an in-memory asset store (the simplest `AssetStore` adapter). Content-addressed by SHA-256 hex of the bytes (CAS; D10). A missing hash resolves to `not-found`, never a placeholder buffer.
createNodeImageCodecfunctioncreateNodeImageCodec(): ImageCodecCreate the node (`sharp`-backed) image codec.
createNodeTextRasterizerfunctioncreateNodeTextRasterizer(): TextRasterizerCreate the Node (`sharp`/librsvg-backed) text rasterizer port adapter.
AssetStoreinterfaceinterface AssetStoreResolve content-addressed asset bytes. A missing hash is `not-found`, never a placeholder.
DecodedImageinterfaceinterface DecodedImageA decoded float RGBA image buffer (no 8-bit intermediates inside the pipeline).
ImageCodecinterfaceinterface ImageCodecDecode/encode pixel buffers. Integer precision appears only at this boundary.
ColorSpaceTagtypetype ColorSpaceTagThe explicit color-space tag carried on a decoded buffer. A named discriminated union (no `null`/`optional`): an untagged source still yields a defined tag (`srgb`) observably, never an absent one. `unknown-tagged` carries an embedded ICC profile we recognized but cannot name — the bytes are preserved so color-management can resolve it without us guessing a working space (color-space spec; D3).
EncodeTargettypetype EncodeTargetEncoded-output format + parameters.
@faceless-photolib/document-model
Immutable document model and immer-based op-set over the ordered layer stack (insert/remove/reorder, blend/opacity/transform edits, groups, clipping, masks, locks) for faceless-photolib.
@faceless-photolib/render-graph
Compiles a faceless-photolib document layer stack into a color-managed, backend-agnostic render graph of GPU passes, with the GpuBackend and TextRasterizer port definitions.