in src/lib/utils/file.ts [26:74]
export async function compressBase64Image(options: CompressBase64Options): Promise<string> {
const {
base64,
maxSizeKB,
outputFormat = "image/jpeg",
minQuality = 0.1,
maxQuality = 1.0,
maxIterations = 10,
} = options;
const img = await new Promise<HTMLImageElement>((resolve, reject) => {
const image = new Image();
image.crossOrigin = "Anonymous";
image.onload = () => resolve(image);
image.onerror = reject;
image.src = base64;
});
const canvas = document.createElement("canvas");
canvas.width = img.width;
canvas.height = img.height;
const ctx = canvas.getContext("2d");
if (!ctx) throw new Error("Could not get canvas context");
ctx.drawImage(img, 0, 0);
let minQ = minQuality;
let maxQ = maxQuality;
let bestBase64 = "";
for (let i = 0; i < maxIterations; i++) {
const q = (minQ + maxQ) / 2;
const b64 = canvas.toDataURL(outputFormat, q);
const size = getBase64ImageSize(b64).kilobytes;
if (size > maxSizeKB) {
maxQ = q;
} else {
minQ = q;
bestBase64 = b64;
}
}
// If no quality produced a small enough image, return the lowest quality result
if (!bestBase64) {
bestBase64 = canvas.toDataURL(outputFormat, minQuality);
}
return bestBase64;
}