The purpose
I’m trying to display a local image file on an HTML canvas.
I found a few examples online, but none of them worked.
(No errors were output, and nothing appeared on the canvas.)
Environment
Chrome:131.0.6778.86
Tried Code
HTML
<input type="file" id="file" accept="image/png, image/jpeg"></div>
<canvas id="canvas"></canvas>
JavaScript
document.getElementById("file").onchange = (event) => {
const file = event.target.files[0];
if(!file.type.match(/^image\/(png|jpeg)$/)) return ;
const reader = new FileReader();
reader.onload = (event) => {
const img = new Image();
img.src = reader.result;
canvas.width = img.width;
canvas.height = img.height;
canvas.getContext('2d').drawImage(img, 0, 0);
}
reader.readAsDataURL(file);
}
When a file is selected, an Image object is created and the selected image is assigned to its src
attribute.
The created Image is then drawn onto a Canvas using drawImage
. It seems correct, but it didn’t work on my system.
Step
The issue was resolved by modifying the JavaScript code.
The code that manipulates the img element after setting its src attribute is now executed after a brief delay using setTimeout
, ensuring the browser has time to become idle.
document.getElementById("file").onchange = (event) => {
const file = event.target.files[0];
if(!file.type.match(/^image\/(png|jpeg|gif)$/)) return ;
const reader = new FileReader();
reader.onload = (event) => {
const img = new Image();
img.src = reader.result;
setTimeout( ()=> {
canvas.width = img.width;
canvas.height = img.height;
canvas.getContext('2d').drawImage(img, 0, 0);
});
}
reader.readAsDataURL(file);
}
Aside
In my environment, img.width
was 0 when canvas.width = img.width;
was called. Therefore, I assumed the img
was not yet fully loaded, and added a setTimeout
call to address this.
Aside2
It worked on a site that runs almost the same code in a sandbox environment. There must be some other factor at play. (Is it a problem with my code or a timing issue?)
Result
I was able to display a local image file on the canvas.
comment