image-js
Version:
Image processing and manipulation in JavaScript
71 lines (62 loc) • 2.08 kB
text/typescript
import type { Mask } from '../Mask.js';
import type { Point } from '../utils/geometry/points.js';
import type { GetBorderPointsOptions } from './maskAnalysis.types.js';
// TODO: This function could be optimised by following the contour instead of scanning all pixels.
/**
* Return an array with the coordinates of the pixels that are on the border of the mask.
* The reference is the top-left corner of the ROI.
* @param mask - Mask to process.
* @param options - Get border points options.
* @returns The array of border pixels.
*/
export function getBorderPoints(
mask: Mask,
options: GetBorderPointsOptions = {},
): Point[] {
const { innerBorders = false, allowCorners = false } = options;
if (!innerBorders) {
mask = mask.solidFill();
}
const borders: Point[] = [];
// first process frame pixels
for (let column = 0; column < mask.width; column++) {
if (mask.getBit(column, 0)) {
borders.push({ column, row: 0 });
}
if (mask.getBit(column, mask.height - 1)) {
borders.push({ column, row: mask.height - 1 });
}
}
for (let row = 0; row < mask.height; row++) {
if (mask.getBit(0, row)) {
borders.push({ column: 0, row });
}
if (mask.getBit(mask.width - 1, row)) {
borders.push({ column: mask.width - 1, row });
}
}
for (let row = 1; row < mask.height - 1; row++) {
for (let column = 1; column < mask.width - 1; column++) {
if (mask.getBit(column, row)) {
if (
mask.getBit(column - 1, row) === 0 ||
mask.getBit(column, row - 1) === 0 ||
mask.getBit(column + 1, row) === 0 ||
mask.getBit(column, row + 1) === 0
) {
borders.push({ column, row });
}
if (
allowCorners &&
(mask.getBit(column - 1, row - 1) === 0 ||
mask.getBit(column - 1, row + 1) === 0 ||
mask.getBit(column + 1, row - 1) === 0 ||
mask.getBit(column + 1, row + 1) === 0)
) {
borders.push({ column, row });
}
}
}
}
return borders;
}