@watercolorizer/tracer


An extremely simple, but efficient, method to create polygonal outlines of 1-bit bitmap images; where zero is an "empty" pixel, and any non-zero value is considered "filled".
Installation
For node, install with npm:
npm i @watercolorizer/tracer
In browsers, import it from an ESM CDN:
<script type="module">
import { trace } from 'https://unpkg.com/@watercolorizer/tracer/dist/index.js'
</script>
Getting Started
import { trace } from '@watercolorizer/tracer';
const bitmapSize: [width: number, height: number] = [100, 100];
const pixelData = new Uint8ClampedArray(bitmapSize[0] * bitmapSize[1]);
/* fill pixelData with 1bit data */
const loops = trace(pixelData, bitmapSize);
loops.forEach(() => {
/* render each loop */
});
Example rendering with HTML <canvas>:
const ctx: CanvasRenderingContext2D = canvas.getContext('2d');
ctx.beginPath();
loops.forEach((loop) => {
const [first, ...rest] = loop;
ctx.moveTo(...first);
rest.forEach((p) => ctx.lineTo(...p));
ctx.lineTo(...first);
});
ctx.fillStyle = 'black';
ctx.fill('evenodd');
Options
limit- Limit the total number of loops returned. Default:16polygonify- Simplify the pixel trace into a polygonal approximation. Default:truedespeckle- Remove loops that have a bounding box are smaller than this value. Default:falseturnPolicy- Which direct to turn when loop direction is ambigous, either"ccw"(counter-clockwise) or"cw"(clockwise) from the current direction. Default:"ccw"
const bitmapSize: [width: number, height: number] = [100, 100];
const pixelData = new Uint8ClampedArray(bitmapSize[0] * bitmapSize[1]);
const loops = trace(pixelData, bitmapSize, {
limit: 1, // stop after resolving a single loop
polygonify: false, // do not polygonify
});
Future work
- Phase 2: Improved Polygonal path simplification.
- Phase 3: Bezier appoximations