image-js
Version:
Image processing and manipulation in JavaScript
140 lines • 4.47 kB
JavaScript
import { match } from 'ts-pattern';
export const BorderType = {
CONSTANT: 'constant',
REPLICATE: 'replicate',
REFLECT: 'reflect',
WRAP: 'wrap',
REFLECT_101: 'reflect101',
};
/**
* Pick the border interpolation algorithm.
* The different algorithms are illustrated here:
* @see {@link https://vovkos.github.io/doxyrest-showcase/opencv/sphinx_rtd_theme/enum_cv_BorderTypes.html}
* @param type - The border type.
* @param value - A pixel value if BorderType.CONSTANT is used.
* @returns The border interpolation function.
*/
export function getBorderInterpolation(type, value) {
if (typeof value === 'number') {
value = new Array(4).fill(value);
}
return match(type)
.with('constant', () => getInterpolateConstant(value))
.with('replicate', () => interpolateReplicate)
.with('reflect', () => interpolateReflect)
.with('reflect101', () => interpolateReflect101)
.with('wrap', () => interpolateWrap)
.exhaustive();
}
function checkRange(point, length) {
if (point <= 0 - length || point >= length + length - 1) {
throw new RangeError('border must be smaller than the original image');
}
}
function getInterpolateConstant(value) {
return function interpolateConstant(column, row, channel, image) {
const newColumn = interpolateConstantPoint(column, image.width);
const newRow = interpolateConstantPoint(row, image.height);
if (newColumn === -1 || newRow === -1) {
return value[channel];
}
return image.getValue(newColumn, newRow, channel);
};
}
/**
* Interpolate using a constant point.
* @param point - The point to interpolate.
* @param length - The length of the image.
* @returns The interpolated point.
*/
export function interpolateConstantPoint(point, length) {
if (point >= 0 && point < length) {
return point;
}
return -1;
}
function interpolateReplicate(column, row, channel, image) {
return image.getValue(interpolateReplicatePoint(column, image.width), interpolateReplicatePoint(row, image.height), channel);
}
/**
* Interpolate by replicating the border.
* @param point - The point to interpolate.
* @param length - The length of the image.
* @returns The interpolated point.
*/
export function interpolateReplicatePoint(point, length) {
if (point >= 0 && point < length) {
return point;
}
checkRange(point, length);
if (point < 0) {
return 0;
}
else {
return length - 1;
}
}
function interpolateReflect(column, row, channel, image) {
return image.getValue(interpolateReflectPoint(column, image.width), interpolateReflectPoint(row, image.height), channel);
}
/**
* Interpolate by reflecting the border.
* @param point - The point to interpolate.
* @param length - The length of the image.
* @returns The interpolated point.
*/
export function interpolateReflectPoint(point, length) {
if (point >= 0 && point < length) {
return point;
}
checkRange(point, length);
if (point < 0) {
return -1 - point;
}
else {
return length + length - 1 - point;
}
}
function interpolateWrap(column, row, channel, image) {
return image.getValue(interpolateWrapPoint(column, image.width), interpolateWrapPoint(row, image.height), channel);
}
/**
* Interpolate by wrapping the border.
* @param point - The point to interpolate.
* @param length - The length of the image.
* @returns The interpolated point.
*/
export function interpolateWrapPoint(point, length) {
if (point >= 0 && point < length) {
return point;
}
checkRange(point, length);
if (point < 0) {
return length + point;
}
else {
return point - length;
}
}
function interpolateReflect101(column, row, channel, image) {
return image.getValue(interpolateReflect101Point(column, image.width), interpolateReflect101Point(row, image.height), channel);
}
/**
* Interpolate by reflecting the border.
* @param point - The point to interpolate.
* @param length - The length of the image.
* @returns The interpolated point.
*/
export function interpolateReflect101Point(point, length) {
if (point >= 0 && point < length) {
return point;
}
checkRange(point, length);
if (point < 0) {
return 0 - point;
}
else {
return length + length - 2 - point;
}
}
//# sourceMappingURL=interpolateBorder.js.map