Skip to content

Commit

Permalink
fix: resize large images attachments on upload (#1824)
Browse files Browse the repository at this point in the history
  • Loading branch information
zaidhaan authored Feb 28, 2023
1 parent 2842a5f commit 32eaee8
Show file tree
Hide file tree
Showing 2 changed files with 58 additions and 2 deletions.
58 changes: 57 additions & 1 deletion composables/masto/publish.ts
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,62 @@ export function useUploadMediaAttachment(draftRef: Ref<Draft>) {
let failedAttachments = $ref<MediaAttachmentUploadError[]>([])
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[]) {
isUploading = true
failedAttachments = []
Expand All @@ -131,7 +187,7 @@ export function useUploadMediaAttachment(draftRef: Ref<Draft>) {
isExceedingAttachmentLimit = false
try {
const attachment = await client.v1.mediaAttachments.create({
file,
file: await processFile(file),
})
draft.attachments.push(attachment)
}
Expand Down
2 changes: 1 addition & 1 deletion nuxt.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -206,7 +206,7 @@ export default defineNuxtConfig({
'font-src': ['\'self\''],
'form-action': ['\'none\''],
'frame-ancestors': ['\'none\''],
'img-src': ['\'self\'', 'https:', 'http:', 'data:'],
'img-src': ['\'self\'', 'https:', 'http:', 'data:', 'blob:'],
'media-src': ['\'self\'', 'https:', 'http:'],
'object-src': ['\'none\''],
'script-src': ['\'self\'', '\'unsafe-inline\'', '\'wasm-unsafe-eval\''],
Expand Down

0 comments on commit 32eaee8

Please sign in to comment.