(with solution code)How to Display Local Files in Canvas

This article can be read in about 4 minutes.
PR

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.)

PR

Environment

Chrome:131.0.6778.86

PR

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.

PR

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?)

PR

Result

I was able to display a local image file on the canvas.

comment

Copied title and URL