|
|
@ -9,35 +9,40 @@ export async function generateThumbnail( |
|
|
quality: number = 0.6 |
|
|
quality: number = 0.6 |
|
|
): Promise<string> { |
|
|
): Promise<string> { |
|
|
if (!base64DataUrl) return base64DataUrl; |
|
|
if (!base64DataUrl) return base64DataUrl; |
|
|
|
|
|
if (!base64DataUrl.startsWith("data:image/")) return base64DataUrl; |
|
|
|
|
|
|
|
|
return new Promise((resolve) => { |
|
|
return new Promise((resolve) => { |
|
|
const img = new Image(); |
|
|
const img = new Image(); |
|
|
img.onload = () => { |
|
|
img.onload = () => { |
|
|
const { naturalWidth: w, naturalHeight: h } = img; |
|
|
try { |
|
|
|
|
|
const { naturalWidth: w, naturalHeight: h } = img; |
|
|
|
|
|
|
|
|
// Skip if already small enough
|
|
|
// Skip if already small enough
|
|
|
if (w <= maxDim && h <= maxDim) { |
|
|
if (w <= maxDim && h <= maxDim) { |
|
|
resolve(base64DataUrl); |
|
|
resolve(base64DataUrl); |
|
|
return; |
|
|
return; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
// Calculate scaled dimensions preserving aspect ratio
|
|
|
// Calculate scaled dimensions preserving aspect ratio
|
|
|
const scale = Math.min(maxDim / w, maxDim / h); |
|
|
const scale = Math.min(maxDim / w, maxDim / h); |
|
|
const newW = Math.round(w * scale); |
|
|
const newW = Math.round(w * scale); |
|
|
const newH = Math.round(h * scale); |
|
|
const newH = Math.round(h * scale); |
|
|
|
|
|
|
|
|
const canvas = document.createElement("canvas"); |
|
|
const canvas = document.createElement("canvas"); |
|
|
canvas.width = newW; |
|
|
canvas.width = newW; |
|
|
canvas.height = newH; |
|
|
canvas.height = newH; |
|
|
|
|
|
|
|
|
const ctx = canvas.getContext("2d"); |
|
|
const ctx = canvas.getContext("2d"); |
|
|
if (!ctx) { |
|
|
if (!ctx) { |
|
|
|
|
|
resolve(base64DataUrl); |
|
|
|
|
|
return; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
ctx.drawImage(img, 0, 0, newW, newH); |
|
|
|
|
|
resolve(canvas.toDataURL("image/jpeg", quality)); |
|
|
|
|
|
} catch { |
|
|
resolve(base64DataUrl); |
|
|
resolve(base64DataUrl); |
|
|
return; |
|
|
|
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
ctx.drawImage(img, 0, 0, newW, newH); |
|
|
|
|
|
resolve(canvas.toDataURL("image/jpeg", quality)); |
|
|
|
|
|
}; |
|
|
}; |
|
|
img.onerror = () => resolve(base64DataUrl); |
|
|
img.onerror = () => resolve(base64DataUrl); |
|
|
img.src = base64DataUrl; |
|
|
img.src = base64DataUrl; |
|
|
|