Created
August 3, 2024 19:53
-
-
Save pkorac/b38b138555c5a1e618ad676f00c02262 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<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> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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