Attempting to draw an image to a Canvas using the Canvas_API but no image is rendered

I am trying to render an image uploaded by the user using an <input> tag with an on change event listener in javascript. However the image will not render.

All of the code below is the browser rendering static files on my local machine. There is no HTTP request/response cycle happening.

Here is my Javascript:

//test to see if I can auto render an image from a browser function
function loadImage(event) {
    
    image_element = document.createElement("img");
    image_element.src = URL.createObjectURL(event.target.files[0]);

    var canvas_wdith = image_element.width;
    var canvas_height = image_element.height;

    canvas_element.width = canvas_wdith;
    canvas_element.height = canvas_height;
    context = canvas_element.getContext("2d");


    context.drawImage(image_element, 0, 0);
    URL.revokeObjectURL(image_element.src);
}

// get both the input and canvas tags from the page.
file = document.getElementById("picture");
canvas_element = document.getElementById("current_image");

file.addEventListener("change", loadImage);

Here is the html I’m using to render the page:

<!DOCTYPE html>
<!--modified from template found at https://www.freecodecamp.org/news/basic-html5-template-boilerplate-code-example -->
<html lang="en">
  <head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Color Descriptor Application</title>
    <link rel="stylesheet" href="">
  </head>
  <body>
      <h1>Color Descriptor Application</h1>
      <label for="picture"> Choose a picture</label>
      <input type="file" id="picture" accept="image/*"/>
      <p></p>
      <canvas id="current_image">
      </canvas>
	  <script src="index.js"></script>
  </body>
</html>

Things I have already tried:

  • I have wrapped the last two lines of the loadImage function into an anonymous function that is triggered in an onload event handler like this stackOverflow example:
base_image.onload = function(){
    context.drawImage(base_image, 0, 0);
  }

None of these gave me any hints as to what was wrong. I know I did something wrong with one of the API calls. I’m just not sure what.

First, you need to ensure that you are waiting for the image to be fully loaded before attempting to draw it onto the canvas. You can achieve this by listening for the ‘load’ event on the image element.

Here’s the modified JavaScript code:

// Function to load image when input changes
function loadImage(event) {
    // Get the file from the input
    const file = event.target.files[0];

    // Create a new image element
    const image_element = new Image();

    // Event listener for when the image is loaded
    image_element.onload = function() {
        // Get canvas element
        const canvas_element = document.getElementById("current_image");
        const context = canvas_element.getContext("2d");

        // Set canvas dimensions to match image
        canvas_element.width = this.width;
        canvas_element.height = this.height;

        // Draw the image onto the canvas
        context.drawImage(this, 0, 0);
    };

    // Set the source of the image to the file object
    image_element.src = URL.createObjectURL(file);
}

// Get the input element and add event listener
const fileInput = document.getElementById("picture");
fileInput.addEventListener("change", loadImage);

i hope With these adjustments, the image should be properly loaded and rendered onto the canvas when a file is selected using the input element.

Thank you this worked. But I have a question

  • How come you put the all of the code for creating the canvas context inside the anonymous function? Couldn’t getting the element and setting the context be placed outside of the function?