UNPKG

@paroicms/server-image-cache-engine

Version:

The image variant engine that we use at Paroi.

59 lines 2.29 kB
import sharp from "sharp"; import { authorizedMediaTypes } from "../constants.js"; import { sharpQueue } from "../image-processor-setup.js"; const icoEndec = (await import("ico-endec")).default; export async function resizeImage(options) { if (options.formatTo?.mediaType === "image/x-icon") return await resizeIcoImage(options); const sharpFormat = options.formatTo ? convertMediaTypeToSharpFormat(options.formatTo.mediaType) : "webp"; const sharpInst = sharp(options.binaryFile) .resize({ width: options.rawSize.rawWidth, height: options.rawSize.rawHeight }) .toFormat(sharpFormat, { quality: getQuality(options.rawSize), lossless: options.formatTo?.lossless, }); const { data, info } = await sharpQueue(() => sharpInst.toBuffer({ resolveWithObject: true })); return { rawWidth: info.width, rawHeight: info.height, weightB: data.byteLength, mediaType: convertSharpFormatToMediaType(info.format), binaryFile: data, }; } export async function resizeIcoImage(options) { const { data, info } = await sharpQueue(() => sharp(options.binaryFile) .resize({ width: options.rawSize.rawWidth, height: options.rawSize.rawHeight }) .toFormat("png") .toBuffer({ resolveWithObject: true })); const binaryFile = icoEndec.encode([data]); return { rawWidth: info.width, rawHeight: info.height, weightB: binaryFile.byteLength, mediaType: "image/x-icon", binaryFile, }; } function convertMediaTypeToSharpFormat(mediaType) { if (!mediaType.startsWith("image/") || !authorizedMediaTypes.has(mediaType)) { throw new Error(`invalid media-type '${mediaType}'`); } return mediaType.substring(6); } export function convertSharpFormatToMediaType(format) { if (format === "svg") return "image/svg+xml"; // Sharp omit +xml return `image/${format}`; } export function getQuality({ rawWidth, rawHeight }, qualityPolicy) { const area = rawWidth * rawHeight; for (const { quality, areaLimitPx } of qualityPolicy ?? []) { if (areaLimitPx === undefined || area <= areaLimitPx) return quality; } return 70; } //# sourceMappingURL=resizer.js.map