UNPKG

image-js

Version:

Image processing and manipulation in JavaScript

144 lines 4.87 kB
import { Image } from '../Image.js'; import { getOutputImage, maskToOutputImage } from '../utils/getOutputImage.js'; /** * Convert image to a different color model. * @param image - Image to convert. * @param colorModel - New color model. * @param options - Convert color options. * @returns The converted image. */ export function convertColor(image, colorModel, options = {}) { const canConvert = new Map([ ['GREY', ['GREYA', 'RGB', 'RGBA']], ['GREYA', ['GREY', 'RGB', 'RGBA']], ['RGB', ['GREY', 'GREYA', 'RGBA']], ['RGBA', ['GREY', 'GREYA', 'RGB']], ['BINARY', ['GREY', 'RGB', 'RGBA']], ]); if (image.colorModel === colorModel && colorModel !== 'BINARY') { return getOutputImage(image, { out: options.out }, { clone: true }); } const canConvertTo = canConvert.get(image.colorModel); if (!canConvertTo?.includes(colorModel)) { throw new RangeError(`conversion from ${image.colorModel} to ${colorModel} not implemented`); } if (image instanceof Image) { const output = getOutputImage(image, options, { newParameters: { colorModel }, }); if (image.colorModel === 'GREY' || image.colorModel === 'GREYA') { convertGreyToAny(image, output); } if (image.colorModel === 'RGB' || image.colorModel === 'RGBA') { if (colorModel === 'RGB' || colorModel === 'RGBA') { convertRgbToRgb(image, output); } else { // GREYA or GREY convertRgbToGrey(image, output); } } if (!image.alpha && output.alpha) { output.fillAlpha(output.maxValue); } if (image.alpha && output.alpha) { copyAlpha(image, output); } return output; } else if (colorModel === 'GREY') { const output = maskToOutputImage(image, options); convertBinaryToGrey(image, output); return output; } else { const img = new Image(image.width, image.height, { colorModel, }); convertBinaryToRgb(image, img); return img; } } /** * Copy alpha channel of source to dest. * @param source - Source image. * @param dest - Destination image. */ export function copyAlpha(source, dest) { if (source.size !== dest.size) { throw new RangeError('source and destination have different sizes'); } if (!source.alpha) { throw new RangeError('source image does not have alpha'); } if (!dest.alpha) { throw new RangeError('destination does not have alpha'); } for (let i = 0; i < dest.size; i++) { dest.setValueByIndex(i, dest.channels - 1, source.getValueByIndex(i, source.channels - 1)); } } /** * Convert grey image to other color model. * @param image - Image to convert. * @param newImage - Converted image. */ function convertGreyToAny(image, newImage) { for (let i = 0; i < image.size; i++) { for (let j = 0; j < newImage.components; j++) { newImage.setValueByIndex(i, j, image.getValueByIndex(i, 0)); } } } /** * Convert RGB image to RGB. Allows to use convert with an RGB target whatever the image color model is. * @param image - Image to convert. * @param newImage - Converted image. */ function convertRgbToRgb(image, newImage) { for (let i = 0; i < image.size; i++) { for (let j = 0; j < 3; j++) { newImage.setValueByIndex(i, j, image.getValueByIndex(i, j)); } } } /** * Convert RGB image to GREY. * @param image - Image to convert. * @param newImage - Converted image. */ function convertRgbToGrey(image, newImage) { for (let i = 0; i < image.size; i++) { const r = image.getValueByIndex(i, 0); const g = image.getValueByIndex(i, 1); const b = image.getValueByIndex(i, 2); newImage.setValueByIndex(i, 0, Math.round(0.299 * r + 0.587 * g + 0.114 * b)); } } /** * Convert Mask to GREY. * @param mask - Mask to convert. * @param newImage - Converted image. */ export function convertBinaryToGrey(mask, newImage) { for (let i = 0; i < mask.size; i++) { newImage.setValueByIndex(i, 0, mask.getBitByIndex(i) ? newImage.maxValue : 0); } } /** * Convert mask to RGB or RGBA. * @param mask - Mask to convert. * @param newImage - Converted image. */ export function convertBinaryToRgb(mask, newImage) { const black = new Array(newImage.components).fill(0); const white = new Array(newImage.components).fill(newImage.maxValue); if (newImage.alpha) { black.push(newImage.maxValue); white.push(newImage.maxValue); } for (let i = 0; i < mask.size; i++) { newImage.setPixelByIndex(i, mask.getBitByIndex(i) ? white : black); } } //# sourceMappingURL=convertColor.js.map