fix: resize large images attachments on upload (#1824)

This commit is contained in:
Zaidhaan 2023-03-01 05:58:19 +08:00 committed by GitHub
parent 2842a5f383
commit 32eaee82e2
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 58 additions and 2 deletions

View file

@ -120,6 +120,62 @@ export function useUploadMediaAttachment(draftRef: Ref<Draft>) {
let failedAttachments = $ref<MediaAttachmentUploadError[]>([]) let failedAttachments = $ref<MediaAttachmentUploadError[]>([])
const dropZoneRef = ref<HTMLDivElement>() const dropZoneRef = ref<HTMLDivElement>()
const maxPixels
= currentInstance.value!.configuration?.mediaAttachments?.imageMatrixLimit
?? 4096 ** 2
const loadImage = (inputFile: Blob) => new Promise<HTMLImageElement>((resolve, reject) => {
const url = URL.createObjectURL(inputFile)
const img = new Image()
img.onerror = err => reject(err)
img.onload = () => resolve(img)
img.src = url
})
function resizeImage(img: CanvasImageSource, type = 'image/png'): Promise<Blob | null> {
const { width, height } = img
const aspectRatio = (width as number) / (height as number)
const canvas = document.createElement('canvas')
const resizedWidth = canvas.width = Math.round(Math.sqrt(maxPixels * aspectRatio))
const resizedHeight = canvas.height = Math.round(Math.sqrt(maxPixels / aspectRatio))
const context = canvas.getContext('2d')
context?.drawImage(img, 0, 0, resizedWidth, resizedHeight)
return new Promise((resolve) => {
canvas.toBlob(resolve, type)
})
}
async function processImageFile(file: File) {
try {
const image = await loadImage(file) as HTMLImageElement
if (image.width * image.height > maxPixels)
file = await resizeImage(image, file.type) as File
return file
}
catch (e) {
// Resize failed, just use the original file
console.error(e)
return file
}
}
async function processFile(file: File) {
if (file.type.startsWith('image/'))
return await processImageFile(file)
return file
}
async function uploadAttachments(files: File[]) { async function uploadAttachments(files: File[]) {
isUploading = true isUploading = true
failedAttachments = [] failedAttachments = []
@ -131,7 +187,7 @@ export function useUploadMediaAttachment(draftRef: Ref<Draft>) {
isExceedingAttachmentLimit = false isExceedingAttachmentLimit = false
try { try {
const attachment = await client.v1.mediaAttachments.create({ const attachment = await client.v1.mediaAttachments.create({
file, file: await processFile(file),
}) })
draft.attachments.push(attachment) draft.attachments.push(attachment)
} }

View file

@ -206,7 +206,7 @@ export default defineNuxtConfig({
'font-src': ['\'self\''], 'font-src': ['\'self\''],
'form-action': ['\'none\''], 'form-action': ['\'none\''],
'frame-ancestors': ['\'none\''], 'frame-ancestors': ['\'none\''],
'img-src': ['\'self\'', 'https:', 'http:', 'data:'], 'img-src': ['\'self\'', 'https:', 'http:', 'data:', 'blob:'],
'media-src': ['\'self\'', 'https:', 'http:'], 'media-src': ['\'self\'', 'https:', 'http:'],
'object-src': ['\'none\''], 'object-src': ['\'none\''],
'script-src': ['\'self\'', '\'unsafe-inline\'', '\'wasm-unsafe-eval\''], 'script-src': ['\'self\'', '\'unsafe-inline\'', '\'wasm-unsafe-eval\''],