chamesu
Version:
This package contains all packages of the chat application.
95 lines (81 loc) • 3.07 kB
text/typescript
/*
* 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<ImageResizeResponse[]> {
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<ImageResizeResponse>[] = [];
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<ImageResizeResponse>(((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
}