36 lines
1.3 KiB
TypeScript
36 lines
1.3 KiB
TypeScript
import type { Mat } from '@techstark/opencv-js';
|
||
import type { CV } from '../../src/lib/opencv-loader';
|
||
import type { RasterImage } from '../../src/lib/types';
|
||
|
||
/** Grayscale RGBA image where `paint(x, y)` returns the brightness 0–255. */
|
||
export function grayImage(width: number, height: number, paint: (x: number, y: number) => number): RasterImage {
|
||
const data = new Uint8ClampedArray(width * height * 4);
|
||
for (let y = 0; y < height; y++) {
|
||
for (let x = 0; x < width; x++) {
|
||
const i = (y * width + x) * 4;
|
||
const v = paint(x, y);
|
||
data[i] = data[i + 1] = data[i + 2] = v;
|
||
data[i + 3] = 255;
|
||
}
|
||
}
|
||
return { width, height, data };
|
||
}
|
||
|
||
/** CV_8UC1 mask with 255 where `inside(x, y)`. Caller must delete it. */
|
||
export function maskFrom(cv: CV, width: number, height: number, inside: (x: number, y: number) => boolean): Mat {
|
||
const mask = cv.Mat.zeros(height, width, cv.CV_8UC1) as Mat;
|
||
const data = mask.data;
|
||
for (let y = 0; y < height; y++) {
|
||
for (let x = 0; x < width; x++) {
|
||
if (inside(x, y)) data[y * width + x] = 255;
|
||
}
|
||
}
|
||
return mask;
|
||
}
|
||
|
||
export const inRect = (x: number, y: number, x0: number, y0: number, x1: number, y1: number) =>
|
||
x >= x0 && x < x1 && y >= y0 && y < y1;
|
||
|
||
export const inCircle = (x: number, y: number, cx: number, cy: number, r: number) =>
|
||
(x - cx) ** 2 + (y - cy) ** 2 <= r * r;
|