[Solution code available] Displaying local files on Canvas

この記事は約5分で読めます。
スポンサーリンク

Things I want to do

This displays a local image file on an HTML canvas.

I found several suggestions when I searched, but when I tried them, they didn’t work.

(No errors were displayed, and nothing appeared on the Canvas.)

スポンサーリンク

Environment

Chrome:131.0.6778.86

スポンサーリンク

Code I tried

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 is created and the selected image is placed in the src attribute.

The created image is being drawn onto the Canvas using `drawImage`. It looks correct, but it didn’t work in my environment.

スポンサーリンク

countermeasure

It worked after modifying the JavaScript code as follows.

The code that manipulates the image after setting the `src` attribute of the image is executed after calling `setTimeout`, which puts the application into an idle state.

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);
}

Side note

In my environment, the value of `img.width` was 0 when `canvas.width = img.width;` was called before the fix. Therefore, I assumed that the `img` object was not in the correct state and added a `setTimeout` call.

Side note 2

The code was working on a site running in a sandbox environment with almost the same code as before the fix.

There might be some other factor at play. (Is it a problem with my code, or is it a timing issue?)

スポンサーリンク

Result

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

コメント

タイトルとURLをコピーしました