// 移动端拍照原图常 5–12MB,1500–1800px 长边 + JPEG 0.85 已经够看清楚音符。 // 用 createImageBitmap 的 imageOrientation: 'from-image' 自动按 EXIF 旋转, // 否则横拍照在 canvas 里会变成竖图。 export async function compressImage(file, { maxEdge = 1800, quality = 0.85 } = {}) { if (!file || !file.type || !file.type.startsWith('image/')) return file let bitmap try { bitmap = await createImageBitmap(file, { imageOrientation: 'from-image' }) } catch { return file } const { width, height } = bitmap const scale = Math.min(1, maxEdge / Math.max(width, height)) const w = Math.max(1, Math.round(width * scale)) const h = Math.max(1, Math.round(height * scale)) const canvas = document.createElement('canvas') canvas.width = w canvas.height = h const ctx = canvas.getContext('2d') ctx.drawImage(bitmap, 0, 0, w, h) bitmap.close?.() const blob = await new Promise((res) => canvas.toBlob(res, 'image/jpeg', quality)) if (!blob || blob.size >= file.size) return file const baseName = file.name?.replace(/\.[^.]+$/, '') || 'photo' return new File([blob], `${baseName}.jpg`, { type: 'image/jpeg', lastModified: Date.now() }) }