Skip to content

Instantly share code, notes, and snippets.

@asyarb
Created July 1, 2024 22:27
Show Gist options
  • Save asyarb/7ff61bf8efbd142cc38b785021c004e9 to your computer and use it in GitHub Desktop.
Save asyarb/7ff61bf8efbd142cc38b785021c004e9 to your computer and use it in GitHub Desktop.
Client-side image resizing in TS.
export async function resizeImg(file: File, size = 256): Promise<File> {
const canvas = document.createElement("canvas")
const ctx = canvas.getContext("2d")
invariant(ctx, "Failed to convert image -- (ctx).")
canvas.width = size
canvas.height = size
const bitmap = await createImageBitmap(file)
const { width, height } = bitmap
const ratio = Math.max(size / width, size / height)
const x = (size - width * ratio) / 2
const y = (size - height * ratio) / 2
ctx.drawImage(
bitmap,
0,
0,
width,
height,
x,
y,
width * ratio,
height * ratio,
)
return new Promise((resolve) => {
canvas.toBlob(
(blob) => {
invariant(blob, "Failed to convert image -- (blob).")
const name = file.name.split(".").at(0)
invariant(name, "Invalid file name.")
resolve(new File([blob], name + ".webp", { type: "image/webp" }))
},
"image/webp",
0.8,
)
})
}
@asyarb
Copy link
Author

asyarb commented Jul 1, 2024

Client-side image resizing. It's pretty crude and simple, but it works and is good for resizing things like Avatars prior to uploading to a server or bucket.

Right now there's an assumption that the image is a 1:1 ratio, but that can be modified by changing canvas.width = size to a computation that pulls the file dimensions and modifies it as needed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment