@opengis/fastify-table
Version:
core-plugins
116 lines (115 loc) • 4.8 kB
JavaScript
import path from "node:path";
import sharp from "sharp";
import { imageSize } from "image-size";
import { config, downloadFile, uploadFile, isFileExists, } from "../../../../utils.js";
import grpc from "../../../plugins/grpc/grpc.js";
import getMimeType from "../../../plugins/file/providers/mime/index.js";
const defaultWidth = 400;
const defaultHeight = 240;
const maxWidth = 2000;
const getHeight = (width, size, ratio = 1) => {
if (size && size.toLowerCase().split("x")[1])
return size.toLowerCase().split("x")[1];
if (width)
return width / ratio;
return defaultHeight;
};
const { resizeImage } = grpc();
const transparentGif = Buffer.from("R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7", "base64");
/**
* Апі використовується для зміни розміру фото за шляхом
*/
export default async function resize({ query, }, reply) {
const { filepath, quality, size, w, h, nocache, format, noimage } = query || {};
if (noimage) {
return reply.headers({ "Content-Type": "image/gif" }).send(transparentGif);
}
if (!filepath) {
return reply
.status(400)
.send({ error: "not enough query params: filepath", code: 400 });
}
const basename = path.basename(filepath);
const mimeType = getMimeType(filepath);
if (!mimeType) {
return reply
.status(400)
.send({ error: "invalid query params: filepath", code: 400 });
}
const resizePath1 = size
? filepath.replace(basename, `${size}_resized_${basename}`)
: filepath.replace(basename, `${w || defaultWidth}_${h || (w ? "" : defaultHeight)}_resized_${basename}`);
// get Resize Data
const resizePath2 = format === "webp"
? resizePath1.replace(path.extname(resizePath1), ".webp")
: resizePath1;
const fileExists = await isFileExists(resizePath2);
const originalFileExists = await isFileExists(resizePath2.replace("files/", "files/original/")); // resize-all API compatibility
const resizePath = originalFileExists
? resizePath2.replace("files/", "files/original/")
: resizePath2;
const resizeData = fileExists
? await downloadFile(resizePath, { buffer: true })
: null;
if (resizeData &&
!config.disableCache &&
!nocache &&
process.env.NODE_ENV !== "test") {
return reply
.headers({
"Content-Type": format === "webp" ? "image/webp" : mimeType,
"Cache-control": "max-age=604800",
})
.send(resizeData);
}
// get File Data
const fileData = await downloadFile(filepath, { buffer: true });
if (!fileData?.length) {
return reply
.status(404)
.send({ error: `Файл не знайдено - ${filepath}`, code: 400 });
}
const resizeQuality = Math.min(+(quality || 75), 100);
const { width = defaultWidth, height = defaultHeight } = imageSize(fileData) || {};
const ratio = width / height;
const check = (size?.toLowerCase?.()?.split?.("x") || [])
.concat(w || "", h || "")
.filter((el) => el && +el > maxWidth);
if (check.length) {
return reply
.status(400)
.send({ error: "resize image size too big", code: 400 });
}
const resizeWidth = (h && !w ? +h * ratio : null) ||
(size?.toLowerCase?.()?.split?.("x")?.[1] &&
!size?.toLowerCase?.()?.split?.("x")?.[0]
? +(size?.toLowerCase?.()?.split?.("x")?.[1] || 0) * ratio
: null) ||
(w ? +w : null) ||
(size?.toLowerCase?.()?.split?.("x")?.[0]
? +(size?.toLowerCase?.()?.split?.("x")?.[0] || 0)
: null) ||
Math.min(width, maxWidth);
const resizeHeight = h || getHeight(resizeWidth, size, ratio);
if (config.trace) {
console.log("original width/height/ratio: ", width, height, ratio);
console.log("resize width/height/ratio/quality: ", resizeWidth, resizeHeight, resizeWidth / resizeHeight, resizeQuality);
}
const { result } = await resizeImage({
base64: Buffer.from(fileData).toString("base64"),
width: resizeWidth,
height: resizeHeight,
quality: resizeQuality,
});
await uploadFile(resizePath, Buffer.from(result, "base64"));
if (format === "webp") {
const buffer = await sharp(Buffer.from(result, "base64"))
.webp({ quality: resizeQuality })
.toBuffer({ resolveWithObject: false });
await uploadFile(resizePath2, buffer);
return reply.headers({ "Content-Type": "image/webp" }).send(buffer);
}
return reply
.headers({ "Content-Type": mimeType })
.send(Buffer.from(result, "base64"));
}