diff --git a/frontend/src/views/MyDiary.vue b/frontend/src/views/MyDiary.vue index 5dc58d1..e26b0c3 100644 --- a/frontend/src/views/MyDiary.vue +++ b/frontend/src/views/MyDiary.vue @@ -504,36 +504,38 @@ function readFileAsBase64(file) { }) } -// Compress image if too large (keeps PNG for small images, JPEG for large) -function compressImage(base64, maxSize = 500000) { +// Compress image if too large +function compressImage(base64, maxSize = 500000, maxDim = 800) { return new Promise((resolve) => { if (base64.length <= maxSize) { resolve(base64); return } const img = new Image() img.onload = () => { const canvas = document.createElement('canvas') let w = img.width, h = img.height - const maxDim = 600 + // Shrink progressively until it fits + let scale = 1 if (w > maxDim || h > maxDim) { - const ratio = Math.min(maxDim / w, maxDim / h) - w = Math.round(w * ratio) - h = Math.round(h * ratio) + scale = Math.min(maxDim / w, maxDim / h) } - canvas.width = w - canvas.height = h - canvas.getContext('2d').drawImage(img, 0, 0, w, h) - // Try PNG first, then JPEG with decreasing quality - let result = canvas.toDataURL('image/png') - if (result.length > maxSize) { - let quality = 0.85 - while (quality > 0.2) { + for (let attempt = 0; attempt < 5; attempt++) { + const cw = Math.round(w * scale) + const ch = Math.round(h * scale) + canvas.width = cw + canvas.height = ch + canvas.getContext('2d').drawImage(img, 0, 0, cw, ch) + let quality = 0.8 + let result = canvas.toDataURL('image/jpeg', quality) + while (result.length > maxSize && quality > 0.2) { + quality -= 0.15 result = canvas.toDataURL('image/jpeg', quality) - if (result.length <= maxSize) break - quality -= 0.1 } + if (result.length <= maxSize) { resolve(result); return } + scale *= 0.7 // shrink more } - resolve(result) + // Last resort + resolve(canvas.toDataURL('image/jpeg', 0.3)) } - img.onerror = () => resolve(base64) // fallback: return original + img.onerror = () => resolve(base64) img.src = base64 }) } @@ -589,7 +591,8 @@ async function handleUpload(type, event) { } const maxSize = type === 'bg' ? 1000000 : 500000 - base64 = await compressImage(base64, maxSize) + const maxDim = type === 'bg' ? 1200 : 800 + base64 = await compressImage(base64, maxSize, maxDim) const fieldMap = { logo: 'brand_logo', bg: 'brand_bg', qr: 'qr_code' } const field = fieldMap[type] if (!field) return