inspannings-monitor/lib/profile/avatar-processing.ts
Madhura68 0bf6b96687 Add server-side avatar processing and responsive bottom nav
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-19 22:06:41 +02:00

47 lines
1.1 KiB
TypeScript

import "server-only";
import sharp from "sharp";
import {
PROFILE_AVATAR_MAX_DIMENSION,
PROFILE_AVATAR_STORED_MAX_BYTES,
} from "@/lib/profile/avatar";
const OUTPUT_QUALITY_STEPS = [82, 72, 64] as const;
const OUTPUT_CONTENT_TYPE = "image/webp";
export type ProcessedProfileAvatar = {
buffer: Buffer;
contentType: string;
};
export class ProfileAvatarProcessingError extends Error {}
export async function processProfileAvatar(
file: File,
): Promise<ProcessedProfileAvatar> {
const inputBuffer = Buffer.from(await file.arrayBuffer());
for (const quality of OUTPUT_QUALITY_STEPS) {
const outputBuffer = await sharp(inputBuffer)
.rotate()
.resize({
width: PROFILE_AVATAR_MAX_DIMENSION,
height: PROFILE_AVATAR_MAX_DIMENSION,
fit: "inside",
withoutEnlargement: true,
})
.webp({ quality })
.toBuffer();
if (outputBuffer.byteLength <= PROFILE_AVATAR_STORED_MAX_BYTES) {
return {
buffer: outputBuffer,
contentType: OUTPUT_CONTENT_TYPE,
};
}
}
throw new ProfileAvatarProcessingError(
"De profielfoto blijft te groot na verkleinen.",
);
}