Skip to content

Instantly share code, notes, and snippets.

@pkorac
Created August 3, 2024 19:53
Show Gist options
  • Save pkorac/b38b138555c5a1e618ad676f00c02262 to your computer and use it in GitHub Desktop.
Save pkorac/b38b138555c5a1e618ad676f00c02262 to your computer and use it in GitHub Desktop.
<template>
<div class="w-96 mx-auto py-12 flex flex-col gap-12 items-center">
<h1 class="text-center text-4xl font-bold">Canvas resize</h1>
<img
:src="avatarURL"
alt="Name"
class="w-32 h-32 rounded-full"
v-if="avatarURL"
/>
<div
v-else
class="w-32 h-32 rounded-full bg-gray-200/50 flex justify-center items-center"
></div>
<!-- Native HTML Element for illustration -->
<input type="file" @change="fileAdded" accept="image/*" />
</div>
</template>
<script setup lang="ts">
import resizeImage from "./imageResize";
const avatarURL = ref("");
const IMG_SIZE = 300;
async function fileAdded(e: Event) {
const fileList = (e.target as HTMLInputElement).files as FileList;
if (!fileList.length) return; // no files no fun
const file = fileList[0]; // get the first file (if multiple)
console.log("File to resize", file);
const resizedFile = await resizeImage(file, IMG_SIZE); // this is where the magic happens
console.log("The resized file", resizedFile);
avatarURL.value = URL.createObjectURL(resizedFile); // create a url from the blob (for display)
// could upload the resized file to your backend here
// await client.uploadFile(resizedFile);…
}
</script>
// Resizes image to a square uses "cover" mode
// accepts File (from input) and size in pixels
// returns a new File object (made with blob)
export default async function resizeImage(file: File, size: number = 300) {
return new Promise<File>((resolve) => {
const reader = new FileReader();
reader.onload = (e) => {
const img = new Image();
img.onload = () => {
const canvas = document.createElement("canvas");
const ctx = canvas.getContext("2d");
let width = img.width;
let height = img.height;
// Calculate the aspect ratio
const aspectRatio = width / height;
// Determine the new dimensions for the image to cover the square canvas
let newWidth, newHeight;
if (aspectRatio > 1) {
newHeight = size;
newWidth = size * aspectRatio;
} else {
newWidth = size;
newHeight = size / aspectRatio;
}
// Calculate the coordinates to center the image on the canvas
const xOffset = (newWidth - size) / 2;
const yOffset = (newHeight - size) / 2;
canvas.width = size;
canvas.height = size;
ctx?.clearRect(0, 0, size, size);
ctx?.drawImage(img, -xOffset, -yOffset, newWidth, newHeight);
canvas.toBlob((blob) => {
if (blob) {
const resizedFile = new File([blob], file.name, {
type: file.type,
lastModified: Date.now(),
});
resolve(resizedFile);
}
}, file.type);
};
img.src = e.target?.result as string;
};
reader.readAsDataURL(file);
});
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment