feat: add image transform route with Sharp resize and crop

This commit is contained in:
2026-03-07 22:59:01 -06:00
parent 54c9925eb6
commit a2e0ba405b

View File

@@ -0,0 +1,65 @@
import { Router } from "express";
import multer from "multer";
import sharp from "sharp";
import { TransformRequest } from "../types/image";
const upload = multer({ storage: multer.memoryStorage() });
const router = Router();
router.post(
"/transform",
upload.single("file"),
async (req, res): Promise<void> => {
if (!req.file) {
res.status(400).json({ error: "No file uploaded" });
return;
}
const {
width,
height,
quality,
format = "png",
fit = "inside",
position = "center"
} = req.body as any;
const numericWidth = width ? Number(width) : undefined;
const numericHeight = height ? Number(height) : undefined;
const numericQuality = quality ? Number(quality) : 80;
try {
let image = sharp(req.file.buffer);
image = image.resize({
width: numericWidth,
height: numericHeight,
fit, // "inside" (no crop) or "cover" (crop to fill)
position, // where to crop when fit === "cover"
withoutEnlargement: true
});
if (format === "webp") {
image = image.webp({ quality: numericQuality });
} else if (format === "jpeg") {
image = image.jpeg({ quality: numericQuality });
} else {
image = image.png({ quality: numericQuality, compressionLevel: 9 });
}
const outputBuffer = await image.toBuffer();
res.setHeader("Content-Type", `image/${format}`);
res.setHeader(
"Content-Disposition",
`attachment; filename="output.${format}"`
);
res.send(outputBuffer);
} catch (err) {
console.error(err);
res.status(500).json({ error: "Image processing failed" });
}
}
);
export default router;