UNPKG

@opengis/fastify-table

Version:

core-plugins

116 lines (115 loc) 4.8 kB
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")); }