Integrate BWConverter Into Your Own Workflow
This guide documents the same WebAssembly pipeline that powers the production app. Use it to embed monochrome processing inside headless CMS builds, kiosk apps, or internal proofing tools while keeping every pixel on-device.
Performance Snapshot
All metrics below were captured with the January 2025 build (commit `18f0c22`). Keep track of your own numbers to monitor regressions after custom modifications.
Classic preset + +8 highlights. Deterministic delta-E < 1.2 vs reference TIFF.
Film Noir preset + grain. GPU memory usage stabilises at 420 MB.
Soft preset with shadow recovery for skin retention.
Preset Matrix (From `DEFAULT_PRESETS`)
| Preset | Contrast | Brightness | Highlights | Shadows | Grain | Recommended Usage |
|---|---|---|---|---|---|---|
| Classic | 100 | 100 | 0 | 0 | 0 | Portrait baseline, editorial proofs |
| Dramatic | 160 | 90 | +10 | -20 | 5 | Architecture, moody landscapes |
| Soft | 80 | 110 | -5 | +10 | 0 | Newborn sessions, skin-focused edits |
| Vintage | 120 | 95 | 0 | +5 | 15 | Fashion lookbooks, heritage storytelling |
| High Contrast | 180 | 100 | +20 | -30 | 0 | Product hero shots, poster art |
| Film Noir | 150 | 80 | +15 | -25 | 20 | Cinematic campaigns, dramatic portraiture |
Need a studio-specific look? Duplicate your preferred preset and persist new values through local storage or your CMS schema. The converter automatically reads custom presets when they follow the same shape.
Embed the Converter in Three Moves
Install Core Modules
Import `DEFAULT_PRESETS`, `DOWNLOAD_FORMATS`, and helper utilities from `@/types/image-processing` and `@/lib/image-format`. These keep preset values consistent between single and batch workers.
import { DEFAULT_PRESETS, DOWNLOAD_FORMATS } from '@/types/image-processing'
import { resolveFileInfo, sanitizeBaseName } from '@/lib/image-format'Spin Up the Worker
Both `/worker.js` and `/batch-worker.js` rely on the same WebAssembly engine. Instantiate the worker once, cache the reference, and forward filter payloads as shown in `src/app/page.tsx`.
const worker = new Worker('/worker.js')
worker.postMessage({
imageData,
contrast: filters.contrast,
brightness: filters.brightness,
type: 'preview'
})Enforce Download Governance
Use `downloadCanvasImage` to cap file size and apply safe filenames. The helper respects max byte targets, which prevents oversized deliverables.
await downloadCanvasImage(canvas, {
filename: `${sanitizeBaseName(info.baseName)}-bw.${format.value}`,
mimeType: format.mimeType,
quality: qualityForFormat(format),
maxBytes: sameFormat ? info.size : undefined
})Quality Assurance Checklist
- Generate a preview and a final export for each preset; compare histograms against the reference pack in `/public/wallpapers/black-and-white-image`.
- Validate download payloads stay below client-specified limits using the `maxBytes` flag.
- Log processing times through `performance.now()` to confirm preview turnaround stays under 3 seconds on target hardware.
- Record the preset + manual slider deltas in session storage so batch jobs can reproduce identical outputs.

Include one or more verified outputs in your own documentation so reviewers can trace the origin of sample imagery.
Launch Your Custom Monochrome Workflow
Whether you are building a newsroom proofing deck or a gallery kiosk, the WebAssembly converter adapts to your stack. Pair it with the batch worker for large exports or integrate it into a headless CMS build pipeline.