import { P, match } from 'ts-pattern'; import type { Image } from '../Image.js'; import type { Mask } from '../Mask.js'; import { encodeBmp } from './encodeBmp.js'; import type { EncodeJpegOptions } from './encodeJpeg.js'; import { encodeJpeg } from './encodeJpeg.js'; import type { EncodePngOptions } from './encodePng.js'; import { encodePng } from './encodePng.js'; export const ImageFormat = { PNG: 'png', JPG: 'jpg', JPEG: 'jpeg', BMP: 'bmp', } as const; export type ImageFormat = (typeof ImageFormat)[keyof typeof ImageFormat]; export interface EncodeOptionsPng { format: 'png'; encoderOptions?: EncodePngOptions; } export interface EncodeOptionsJpeg { format: 'jpg' | 'jpeg'; encoderOptions?: EncodeJpegOptions; } export interface EncodeOptionsBmp { format: 'bmp'; } export const defaultPng: EncodeOptionsPng = { format: 'png' }; /** * Encodes the image to the specified format * @param image - Image to encode. * @param options - Format and options passed to the encoder. * @returns The encoded image. */ export function encode( image: Image | Mask, options: EncodeOptionsBmp | EncodeOptionsPng | EncodeOptionsJpeg = defaultPng, ): Uint8Array { return match(options) .with({ format: 'png' }, (options) => encodePng(image, options.encoderOptions), ) .with({ format: P.union('jpg', 'jpeg') }, (options) => encodeJpeg(image, options.encoderOptions), ) .with({ format: 'bmp' }, () => encodeBmp(image)) .exhaustive(); }