piano-sheet(upload): mobile/pad first,主入口直调后置摄像头
deploy piano-sheet / build-and-deploy (push) Successful in 1m17s
deploy piano-sheet / build-and-deploy (push) Successful in 1m17s
- 主 CTA「拍下一页」+ capture=environment,副 CTA「从相册」multiple - 底部 sticky 上传按钮,iOS safe area 兜住刘海/Home indicator - 客户端压缩 1800px JPEG 0.85(createImageBitmap + EXIF 自动旋转) - 页码 ↑↓ 移动 + ✕ 删除替代旧拖拽
This commit is contained in:
@@ -0,0 +1,32 @@
|
||||
// 移动端拍照原图常 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() })
|
||||
}
|
||||
Reference in New Issue
Block a user