UNPKG

image-js

Version:

Image processing and manipulation in JavaScript

63 lines 2.75 kB
import { getClamp } from '../utils/clamp.js'; import { getOutputImage } from '../utils/getOutputImage.js'; import checkProcessable from '../utils/validators/checkProcessable.js'; import { validateChannels } from '../utils/validators/validators.js'; /** * Level the image using the optional input and output value. The default options allow to increase the image's contrast. * @param image - Image to process. * @param options - Level options. * @returns The levelled image. */ export function level(image, options = {}) { const minMax = image.minMax(); let { inputMin = minMax.min, inputMax = minMax.max, outputMin = 0, outputMax = image.maxValue, gamma = 1, } = options; const { channels = new Array(image.components).fill(0).map((value, index) => index), } = options; validateChannels(channels, image); checkProcessable(image, { bitDepth: [8, 16], }); const newImage = getOutputImage(image, options, { clone: true }); const clamp = getClamp(image); inputMin = getValueArray(inputMin, image.channels); inputMax = getValueArray(inputMax, image.channels); outputMin = getValueArray(outputMin, image.channels); outputMax = getValueArray(outputMax, image.channels); gamma = getValueArray(gamma, image.channels); for (let row = 0; row < image.height; row++) { for (let column = 0; column < image.width; column++) { for (const channel of channels) { const currentValue = image.getValue(column, row, channel); const clamped = Math.max(Math.min(currentValue, inputMax[channel]), inputMin[channel]); let ratio = clamp((clamped - inputMin[channel]) / (inputMax[channel] - inputMin[channel])); if (Number.isNaN(ratio)) ratio = 0; const result = clamp(ratio ** (1 / gamma[channel]) * (outputMax[channel] - outputMin[channel]) + outputMin[channel]); newImage.setValue(column, row, channel, result); } } } return newImage; } /** * Get an array with correct values for each channel to process. * @param value - Number or array to transform to the final array. * @param imageChannels - Number of channels processed in the level function. * @returns Array of values for each channel. */ function getValueArray(value, imageChannels) { if (Array.isArray(value)) { if (value.length === imageChannels) { return value; } else { throw new RangeError('array length is not compatible with channel option'); } } else { return new Array(imageChannels).fill(value); } } //# sourceMappingURL=level.js.map