image-js
Version:
Image processing and manipulation in JavaScript
84 lines • 2.88 kB
JavaScript
import { getClamp } from '../utils/clamp.js';
import { getOutputImage } from '../utils/getOutputImage.js';
import { assert } from '../utils/validators/assert.js';
import checkProcessable from '../utils/validators/checkProcessable.js';
import * as greyAlgorithms from './greyAlgorithms.js';
export const GreyAlgorithm = {
LUMA_709: 'luma709',
LUMA_601: 'luma601',
MAX: 'max',
MIN: 'min',
AVERAGE: 'average',
MINMAX: 'minmax',
RED: 'red',
GREEN: 'green',
BLUE: 'blue',
BLACK: 'black',
CYAN: 'cyan',
MAGENTA: 'magenta',
YELLOW: 'yellow',
HUE: 'hue',
SATURATION: 'saturation',
LIGHTNESS: 'lightness',
};
{
// Check that all the algorithms are in the enum.
const algos = new Set(Object.values(GreyAlgorithm));
for (const algo of Object.keys(greyAlgorithms)) {
assert(algos.has(algo), `Grey algorithm ${algo} is missing in the GreyAlgorithm enum`);
}
}
/**
* Convert the current image to grayscale.
* The source image has to be RGB or RGBA.
* If there is an alpha channel you have to specify what to do:
* - keepAlpha : keep the alpha channel, you will get a GREYA image.
* - mergeAlpha : multiply each pixel of the image by the alpha, you will get a GREY image.
* @param image - Original color image to convert to grey.
* @param options - The grey conversion options.
* @returns The resulting grey image.
*/
export function grey(image, options = {}) {
let { keepAlpha = false, mergeAlpha = true } = options;
const { algorithm = 'luma709' } = options;
checkProcessable(image, {
colorModel: ['RGB', 'RGBA'],
});
keepAlpha = keepAlpha && image.alpha;
mergeAlpha = mergeAlpha && image.alpha;
if (keepAlpha) {
mergeAlpha = false;
}
const newColorModel = keepAlpha ? 'GREYA' : 'GREY';
const newImage = getOutputImage(image, options, {
newParameters: { colorModel: newColorModel },
});
let method;
if (typeof algorithm === 'function') {
method = algorithm;
}
else {
method = greyAlgorithms[algorithm];
}
const clamp = getClamp(newImage);
for (let i = 0; i < image.size; i++) {
const red = image.getValueByIndex(i, 0);
const green = image.getValueByIndex(i, 1);
const blue = image.getValueByIndex(i, 2);
let newValue;
if (mergeAlpha) {
const alpha = image.getValueByIndex(i, 3);
newValue = clamp((method(red, green, blue, image) * alpha) / image.maxValue);
}
else {
newValue = clamp(method(red, green, blue, image));
if (keepAlpha) {
const alpha = image.getValueByIndex(i, 3);
newImage.setValueByIndex(i, 1, alpha);
}
}
newImage.setValueByIndex(i, 0, newValue);
}
return newImage;
}
//# sourceMappingURL=grey.js.map