feat: Docs on how to compress / resize an image on the server before upload
Describe the feature you'd like to request
api/uploadthing/core.ts
// FileRouter for your app, can contain multiple FileRoutes export const ourFileRouter = { // Define as many FileRoutes as you like, each with a unique routeSlug imageUploader: f({ image: { maxFileSize: "8MB" } }) // Set permissions and file types for this FileRoute .middleware(async ({ req }) => { // This code runs on your server before upload const user = await auth(req) // explain here
Explain here how to compress an image and resize it before uploading
Describe the solution you'd like to see
Add to the documentation suggested ways of compressing / resizing
Additional information
No response
๐จโ๐งโ๐ฆ Contributing
- [ ] ๐โโ๏ธ Yes, I'd be down to file a PR implementing this feature!
well the short answer is you can't, cause for client-side uploads the file never hits your server. your server is only used to request presigned urls in a secure manner. so if you wanna preprocess the file, you'd do that on the client, for example in the onBeforeUploadBegin callback
if you wanna do this, you'd need to use server-side uploads. Submit the file to your server, do your thing and use utapi.uploadFiles to upload the compressed image.
This issue has been automatically marked as stale because it has not had any activity for 10 days. It will be closed in 5 days if no further activity occurs.
This issue has been closed because it has not had any activity for 5 days since being marked as stale.
I achieved this by creating an imageResizer.ts in my utils folder. I then utilised the onBeforeUploadBegin parameter of the UploadButton (see below).
` function resizeImage(file: File, scaleFactor: number): Promise<Blob> { return new Promise((resolve, reject) => { const img = new Image() img.src = URL.createObjectURL(file)
img.onload = () => {
const canvas = document.createElement('canvas')
const ctx = canvas.getContext('2d')!
const width = Math.floor(img.width * scaleFactor)
const height = Math.floor(img.height * scaleFactor)
canvas.width = width
canvas.height = height
ctx.drawImage(img, 0, 0, width, height)
// Check if toBlob succeeded and the result is not null
canvas.toBlob((blob) => {
if (blob !== null) {
resolve(blob)
} else {
reject(new Error('Failed to generate blob from canvas'))
}
}, file.type)
}
img.onerror = () => {
reject(new Error('Failed to load image'))
}
})
}
export default resizeImage `
onBeforeUploadBegin={async ( files ) => { try { const resizedFiles = await Promise.all( files.map( async ( file ) => { const resizedBlob = await resizeImage( file, 0.2 ) // Resize to 20% of original size return new File( [ resizedBlob, ], file.name, { type: file.type, } ) } ) ) return resizedFiles } catch (error) { console.error( 'Error resizing images:', error ) return files // Return original files if resizing fails } }}