import { sharpenAdvanced } from "@snapotter/image-engine"; import type { FastifyInstance } from "fastify"; import sharp from "sharp"; import { z } from "zod"; import { resolveOutputFormat } from "../../lib/output-format.js"; import { createToolRoute } from "../tool-factory.js"; const settingsSchema = z.object({ method: z.enum(["adaptive", "unsharp-mask", "high-pass"]).default("adaptive"), // Adaptive sigma: z.number().min(0.5).max(10).default(1.0), m1: z.number().min(0).max(10).default(1.0), m2: z.number().min(0).max(20).default(3.0), x1: z.number().min(0).max(10).default(2.0), y2: z.number().min(0).max(50).default(12), y3: z.number().min(0).max(50).default(20), // Unsharp Mask amount: z.number().min(0).max(1000).default(100), radius: z.number().min(0.1).max(5).default(1.0), threshold: z.number().min(0).max(255).default(0), // High-Pass strength: z.number().min(0).max(100).default(50), kernelSize: z.union([z.literal(3), z.literal(5)]).default(3), // Noise reduction denoise: z.enum(["off", "light", "medium", "strong"]).default("off"), }); export function registerSharpening(app: FastifyInstance) { createToolRoute(app, { toolId: "sharpening", settingsSchema, process: async (inputBuffer, settings, filename) => { const outputFormat = await resolveOutputFormat(inputBuffer, filename); let image = sharp(inputBuffer); image = await sharpenAdvanced(image, { method: settings.method, sigma: settings.sigma, m1: settings.m1, m2: settings.m2, x1: settings.x1, y2: settings.y2, y3: settings.y3, amount: settings.amount, radius: settings.radius, threshold: settings.threshold, strength: settings.strength, kernelSize: settings.kernelSize, denoise: settings.denoise, }); const buffer = await image .toFormat(outputFormat.format, { quality: outputFormat.quality }) .toBuffer(); return { buffer, filename, contentType: outputFormat.contentType }; }, }); }