faceless-photolib

@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-codec

Usage

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

ExportDescription
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.
ImageCodecPort interface: decode(bytes) / encode(image, target), each returning a Result.
AssetStorePort interface: resolve(hash) / put(bytes) / has(hash).
DecodedImageA decoded straight-RGBA Float32Array image with width, height, and a colorSpaceTag.
EncodeTargetDiscriminated union of output targets: png / jpeg / exr / tiff.
ColorSpaceTagAlways-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.

createInMemoryAssetStorefunction
createInMemoryAssetStore(): AssetStore

Create 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.

createNodeImageCodecfunction
createNodeImageCodec(): ImageCodec

Create the node (`sharp`-backed) image codec.

createNodeTextRasterizerfunction
createNodeTextRasterizer(): TextRasterizer

Create the Node (`sharp`/librsvg-backed) text rasterizer port adapter.

AssetStoreinterface
interface AssetStore

Resolve content-addressed asset bytes. A missing hash is `not-found`, never a placeholder.

DecodedImageinterface
interface DecodedImage

A decoded float RGBA image buffer (no 8-bit intermediates inside the pipeline).

ImageCodecinterface
interface ImageCodec

Decode/encode pixel buffers. Integer precision appears only at this boundary.

ColorSpaceTagtype
type ColorSpaceTag

The 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).

EncodeTargettype
type EncodeTarget

Encoded-output format + parameters.

On this page