import { json } from "@sveltejs/kit"; import type { RequestHandler } from "./$types"; import { putObject } from "$lib/helpers/minio"; import { generateImage } from "$lib/helpers/stability"; import sharp from "sharp"; async function compressImage(imageName: string, imageBuffer: Buffer) { const ja = performance.now() const jpgBuffer = await sharp(imageBuffer) .jpeg({ quality: 70 }) .withMetadata() .toBuffer(); await putObject(imageName.replace(".png", ".jpg"), jpgBuffer, { "Content-Type": "image/jpeg" }); const jb = performance.now() - ja; console.log(`[AI] JPG compression took ${jb}ms`) const wa = performance.now() const webpBuffer = await sharp(imageBuffer) .webp({ quality: 70 }) .withMetadata() .toBuffer() await putObject(imageName.replace(".png", ".webp"), webpBuffer, { "Content-Type": "image/webp" }); const wb = performance.now() - wa; console.log(`[AI] WebP compression took ${wb}ms`) const aa = performance.now() const aviBuffer = await sharp(imageBuffer) .avif({ quality: 70 }) .withMetadata() .toBuffer() await putObject(imageName.replace(".png", ".avif"), aviBuffer, { "Content-Type": "image/avif" }); const ab = performance.now() - aa; console.log(`[AI] AVIF compression took ${ab}ms`) } export const POST: RequestHandler = async ({ params, request }) => { const inputName = params.name; if (!inputName) { throw new Error("Missing name"); } if (inputName.length > 100) { throw new Error("Name too long"); } const { hairType, hairColor, hairLength, skinColor, name } = await request.json(); console.log(`[AI] Generating image for ${inputName} ${JSON.stringify({ hairType, hairColor, hairLength, skinColor, inputName })}`) if (!hairType || !hairColor || !hairLength) { throw new Error("Missing hairType, hairColor or hairLength"); } const prompt = `realistic sharp portrait oil painting of a masked ${inputName}, baroque, in the style of Charles Vess, masked ball attire, opulence, mystery, elegance, ${hairLength} ${hairType} ${hairColor} hair, ${skinColor} skin`; const negativePrompt = "blurry, multiple persons, picture frame, nsfw" const a = performance.now() const image = await generateImage(prompt, negativePrompt); const d = performance.now() - a; console.log(`[AI] Image generation took ${d}ms`) const imageName = `${Math.random().toString(16).substring(3, 10)}-${inputName.toLowerCase().split(" ").slice(0, 5).join("-").slice(0, 25)}.png` const imageBuffer = Buffer.from(image.base64, 'base64'); const a2 = performance.now() const pngBuffer = await sharp(imageBuffer) .png({ compressionLevel: 9, adaptiveFiltering: true, force: true }) .withMetadata() .toBuffer() await putObject(imageName, pngBuffer, { "Content-Type": "image/png" }); const d2 = performance.now() - a2; console.log(`[AI] PNG compression took ${d2}ms`) await compressImage(imageName, imageBuffer) return json({ url: `https://s3-s24.max-richter.dev/silvester24/${imageName}` }) }