/* * Copyright (c) 2022. * Author Peter Placzek (tada5hi) * For the full copyright and license information, * view the LICENSE file that was distributed with this source code. */ import path from "path"; import {getWritableDirPath} from "../../config/paths"; import * as fs from "fs"; import sharp, {Sharp} from "sharp"; import {v4} from "uuid"; import {ImageCropCoordinates, ImageCropResizeConfig} from "@chamesu/common/domains/image/crop"; import {QueueMessage} from "../../modules/message-queue/type"; /** * Resize image as step in the resolve chain of the image command. * * @param message */ export async function resizeImage(message: QueueMessage) { const srcFilePath : string = path.resolve(getWritableDirPath(), message.data.srcFilePath); const cropCoordinates : ImageCropCoordinates = message.data.cropCoordinates; const cropResizeConfig : ImageCropResizeConfig = message.data.cropResizeConfig; message.resultSizes = await doResizeImage(srcFilePath, cropCoordinates, cropResizeConfig); return message; } /** * Resize image (srcFilePath) and place resized variants of image * to same directory. * * @param srcFilePath * @param cropCoordinates * @param cropResizeConfig */ async function doResizeImage(srcFilePath: string, cropCoordinates: any, cropResizeConfig: ImageCropResizeConfig) : Promise { const buffer: Buffer = fs.readFileSync(srcFilePath); /** * sharp(buffer).png */ const instance: Sharp = sharp(buffer) .extract({ width: cropCoordinates.width, height: cropCoordinates.height, left: cropCoordinates.left, top: cropCoordinates.top }); const promises: Promise[] = []; const destinationPath = path.dirname(srcFilePath); const ratio : string = (cropCoordinates.width / cropCoordinates.height).toFixed(1); for (let i = 0; i < cropResizeConfig.sizes.length; i++) { const fileName: string = v4() + '.png'; const sizePath: string = path.resolve(destinationPath, fileName); const height: number = Number((cropResizeConfig.sizes[i].width / Number(ratio)).toFixed()); promises.push(new Promise(((resolve, reject) => { instance .clone() .resize({ width: cropResizeConfig.sizes[i].width }) .toFile(sizePath, ((err: Error) => { if (err) reject(err); resolve({ dimensions: { width: cropResizeConfig.sizes[i].width, height: height }, file: fileName, name: cropResizeConfig.sizes[i].name }); })); }))); } return Promise.all(promises); } export type ImageResizeResponse = { dimensions: { width: number, height: number }, file: string, name: string }