image-js
Version:
Image processing and manipulation in JavaScript
75 lines (68 loc) • 2 kB
text/typescript
import type { BitDepth, Image } from '../Image.js';
import { getOutputImage } from '../utils/getOutputImage.js';
export interface ConvertBitDepthOptions {
/**
* Image to which to output.
*/
out?: Image;
}
/**
* Convert the bit depth of an image.
* @param image - Image to convert.
* @param newBitDepth - Bit depth to convert to.
* @param options - Convert bit depth options.
* @returns Converted image.
*/
export function convertBitDepth(
image: Image,
newBitDepth: BitDepth,
options: ConvertBitDepthOptions = {},
): Image {
if (image.bitDepth === newBitDepth) {
return getOutputImage(image, options, { clone: true });
}
if (newBitDepth !== 8 && newBitDepth !== 16) {
throw new RangeError(
`This image bit depth is not supported: ${newBitDepth}`,
);
}
// Get the output image first - this handles the out option
const newImage = getOutputImage(image, options, {
clone: false,
newParameters: {
bitDepth: newBitDepth,
colorModel: image.colorModel,
},
});
return newBitDepth === 8
? convertToUint8(image, newImage)
: convertToUint16(image, newImage);
}
/**
* Convert bit depth to 16 bits.
* @param image - Image to convert.
* @param targetImage - Target image to write to.
* @returns Converted image.
*/
function convertToUint16(image: Image, targetImage: Image): Image {
for (let i = 0; i < image.size; i++) {
for (let j = 0; j < targetImage.channels; j++) {
targetImage.setValueByIndex(i, j, image.getValueByIndex(i, j) << 8);
}
}
return targetImage;
}
/**
* Convert bit depth to 8 bits.
* @param image - Image to convert.
* @param targetImage - Target image to write to.
* @returns Converted image.
*/
function convertToUint8(image: Image, targetImage: Image): Image {
for (let i = 0; i < image.size; i++) {
for (let j = 0; j < targetImage.channels; j++) {
targetImage.setValueByIndex(i, j, image.getValueByIndex(i, j) >> 8);
}
}
return targetImage;
}