forked from Mirrors/elk
fix: resize large images attachments on upload (#1824)
This commit is contained in:
parent
2842a5f383
commit
32eaee82e2
2 changed files with 58 additions and 2 deletions
|
@ -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)
|
||||||
}
|
}
|
||||||
|
|
|
@ -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\''],
|
||||||
|
|
Loading…
Reference in a new issue