feat: 监控上传图片压缩
This commit is contained in:
parent
dd9000bf48
commit
23c87c43e1
@ -15,6 +15,9 @@ const MONITOR_SNAPSHOT_INTERVAL = 10000
|
||||
const MONITOR_MSG_TYPE = 'monitorStart'
|
||||
const MONITOR_STOP_MSG_TYPE = 'monitorStop'
|
||||
const MONITOR_LOG_PREFIX = '[class-monitor]'
|
||||
const MONITOR_SNAPSHOT_TARGET_SIZE = 100 * 1024
|
||||
const MONITOR_SNAPSHOT_MIN_WIDTH = 480
|
||||
const MONITOR_SNAPSHOT_MIN_HEIGHT = 270
|
||||
|
||||
const monitorLog = (...args: unknown[]) => console.log(MONITOR_LOG_PREFIX, ...args)
|
||||
const monitorWarn = (...args: unknown[]) => console.warn(MONITOR_LOG_PREFIX, ...args)
|
||||
@ -119,20 +122,84 @@ const prepareMonitorDomForCapture = async () => {
|
||||
})
|
||||
}
|
||||
|
||||
const canvasToPngFile = (canvas: HTMLCanvasElement) =>
|
||||
new Promise<File | null>(resolve => {
|
||||
canvas.toBlob(blob => {
|
||||
if (!blob) return resolve(null)
|
||||
resolve(new File([blob], `monitor-${Date.now()}.png`, { type: 'image/png' }))
|
||||
}, 'image/png')
|
||||
const canvasToBlob = (canvas: HTMLCanvasElement, type: string, quality?: number) =>
|
||||
new Promise<Blob | null>(resolve => {
|
||||
canvas.toBlob(
|
||||
blob => {
|
||||
resolve(blob)
|
||||
},
|
||||
type,
|
||||
quality,
|
||||
)
|
||||
})
|
||||
|
||||
const resizeCanvas = (source: HTMLCanvasElement, ratio: number) => {
|
||||
const canvas = document.createElement('canvas')
|
||||
canvas.width = Math.max(1, Math.round(source.width * ratio))
|
||||
canvas.height = Math.max(1, Math.round(source.height * ratio))
|
||||
const ctx = canvas.getContext('2d')
|
||||
if (!ctx) return source
|
||||
ctx.drawImage(source, 0, 0, canvas.width, canvas.height)
|
||||
return canvas
|
||||
}
|
||||
|
||||
const canvasToMonitorFile = async (canvas: HTMLCanvasElement) => {
|
||||
const qualities = [0.72, 0.6, 0.5, 0.42, 0.35, 0.3, 0.25]
|
||||
let current = canvas
|
||||
let bestBlob: Blob | null = null
|
||||
let bestInfo = {
|
||||
width: canvas.width,
|
||||
height: canvas.height,
|
||||
quality: qualities[0],
|
||||
}
|
||||
|
||||
for (let resizeCount = 0; resizeCount < 8; resizeCount++) {
|
||||
for (const quality of qualities) {
|
||||
const blob = await canvasToBlob(current, 'image/jpeg', quality)
|
||||
if (!blob) return null
|
||||
if (!bestBlob || blob.size < bestBlob.size) {
|
||||
bestBlob = blob
|
||||
bestInfo = {
|
||||
width: current.width,
|
||||
height: current.height,
|
||||
quality,
|
||||
}
|
||||
}
|
||||
if (blob.size <= MONITOR_SNAPSHOT_TARGET_SIZE) {
|
||||
monitorLog('web screenshot compressed', {
|
||||
width: current.width,
|
||||
height: current.height,
|
||||
quality,
|
||||
size: blob.size,
|
||||
})
|
||||
return new File([blob], `monitor-${Date.now()}.jpg`, { type: 'image/jpeg' })
|
||||
}
|
||||
}
|
||||
|
||||
if (
|
||||
current.width <= MONITOR_SNAPSHOT_MIN_WIDTH ||
|
||||
current.height <= MONITOR_SNAPSHOT_MIN_HEIGHT
|
||||
) {
|
||||
break
|
||||
}
|
||||
current = resizeCanvas(current, 0.85)
|
||||
}
|
||||
|
||||
if (!bestBlob) return null
|
||||
monitorWarn('web screenshot compressed but still over target', {
|
||||
...bestInfo,
|
||||
size: bestBlob.size,
|
||||
target: MONITOR_SNAPSHOT_TARGET_SIZE,
|
||||
})
|
||||
return new File([bestBlob], `monitor-${Date.now()}.jpg`, { type: 'image/jpeg' })
|
||||
}
|
||||
|
||||
const createWebScreenshotFile = async (): Promise<File | null> => {
|
||||
await prepareMonitorDomForCapture()
|
||||
|
||||
const vw = window.innerWidth
|
||||
const vh = window.innerHeight
|
||||
const scale = Math.min(window.devicePixelRatio || 1, 2)
|
||||
const scale = Math.min(window.devicePixelRatio || 1, 1)
|
||||
monitorLog('web screenshot start', {
|
||||
href: window.location.href,
|
||||
viewport: `${vw}x${vh}`,
|
||||
@ -200,7 +267,7 @@ const createWebScreenshotFile = async (): Promise<File | null> => {
|
||||
monitorWarn('web screenshot canvas empty', index + 1)
|
||||
continue
|
||||
}
|
||||
const file = await canvasToPngFile(canvas)
|
||||
const file = await canvasToMonitorFile(canvas)
|
||||
if (file) {
|
||||
monitorLog('web screenshot file ready', {
|
||||
attempt: index + 1,
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user