image-js
Version:
Image processing and manipulation in JavaScript
63 lines (53 loc) • 1.82 kB
text/typescript
import type { Image } from '../Image.js';
import { getOutputImage } from '../utils/getOutputImage.js';
import checkProcessable from '../utils/validators/checkProcessable.js';
import { validateChannels } from '../utils/validators/validators.js';
export interface HypotenuseOptions {
/**
* To which channels to apply the filter. By default all but alpha.
*/
channels?: number[];
}
/**
* Calculate a new image that is the hypotenuse between the current image and the otherImage.
* @param image - First image to process.
* @param otherImage - Second image.
* @param options - Hypotenuse options.
* @returns Hypotenuse of the two images.
*/
export function hypotenuse(
image: Image,
otherImage: Image,
options: HypotenuseOptions = {},
): Image {
const {
channels = new Array(image.components).fill(0).map((value, index) => index),
} = options;
checkProcessable(image, {
bitDepth: [8, 16],
});
if (image.width !== otherImage.width || image.height !== otherImage.height) {
throw new RangeError('both images must have the same size');
}
if (
image.alpha !== otherImage.alpha ||
image.bitDepth !== otherImage.bitDepth
) {
throw new RangeError('both images must have the same alpha and bitDepth');
}
if (image.channels !== otherImage.channels) {
throw new RangeError('both images must have the same number of channels');
}
validateChannels(channels, image);
const newImage = getOutputImage(image, {}, { clone: true });
for (const channel of channels) {
for (let i = 0; i < image.size; i++) {
const value = Math.hypot(
image.getValueByIndex(i, channel),
otherImage.getValueByIndex(i, channel),
);
newImage.setValueByIndex(i, channel, Math.min(value, newImage.maxValue));
}
}
return newImage;
}