0

I have a simple demo where users can select an image file, and I want to extract the RGB values of the image file as a ImageData. Here's my attempt:

<form>
  <label for="img">Select image:</label>
  <div>
    <input type="file" id="img" name="img" accept="image/*" onchange="loadImage(this)"> 
  </div>
</form>

<canvas id="origCanvas" .../>

function loadImage(input) {
    if (input.files && input.files[0]) {
        var imageFile = input.files[0]
        var reader = new FileReader();
        reader.onload = function() {
            var img = new Image(CANVAS_WIDTH, CANVAS_HEIGHT);
            img.src = reader.result;
            readRGB(img);
        }
        reader.readAsDataURL(imageFile);
    }
}

function readRGB(img) {
    var c = document.getElementById("origCanvas");
    var ctx = c.getContext("2d");
    ctx.drawImage(img, 0, 0, CANVAS_WIDTH, CANVAS_HEIGHT);
    imageData = ctx.getImageData(0, 0, CANVAS_WIDTH, CANVAS_HEIGHT);
    // do something else
}

However, when I keep selecting different files, readRGB only extracts the correct imageData some of the times. Other times the imageData I extracted are the old imageData that's already there on the canvas.

My gut feeling says that img.src = reader.result is an async operation, and it's at the mercy of the browser when img will be loaded. Many times when I try to ctx.drawImage(img), I end up drawing an empty canvas because img hasn't loaded the actual image file yet.

Is my guess correct, and what should I do in this case?

  • Does this answer your question? [How to create a JavaScript callback for knowing when an image is loaded?](https://stackoverflow.com/questions/280049/how-to-create-a-javascript-callback-for-knowing-when-an-image-is-loaded) – Vasyl Moskalov Jun 15 '20 at 06:00
  • Why is your onChange in comments and without capital? Maybe try this: ```onChange={() => loadImage(this)}``` – Yorbjörn Jun 15 '20 at 07:43

0 Answers0