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".
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');
-
limit
- Limit the total number of loops returned. Default:16
-
polygonify
- Simplify the pixel trace into a polygonal approximation. Default:true
-
despeckle
- Remove loops that have a bounding box are smaller than this value. Default:false
-
turnPolicy
- 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
});
- Phase 2: Improved Polygonal path simplification.
- Phase 3: Bezier appoximations