简体   繁体   中英

JS multiselect images and draw them into canvas - sometimes canvas blank or same image drawn

I am using JS and a multi select field.

A user can select multiple images from a folder and then each image should be drawn into a canvas. Each image has a predefined canvas and a predefined input field where then the decoded base64 dataurl is placed in.

The multiselect field:

<input id="bild" multiple="" name="bild" type="file">

In my example there are 3 different canvas elements and 3 different dataurl input fields:

$( "input#bild" ).change(function() {

  console.log("multiple");

  // from an input element
  var filesToUpload = this.files;
  //console.log(filesToUpload);

  if(typeof this.files[0] !== "undefined") {
    console.log("multiple-1");
    var img = document.createElement("img");
    img.src = window.URL.createObjectURL(this.files[0]);

    $( img ).load(function() {
      console.log("multiple-1-loaded");
      canvas = $("#uploading_canvas_image_1").get(0);                   

      var MAX_WIDTH = 550;
      var MAX_HEIGHT = 400;
      var width = img.width;
      var height = img.height;

      if (width > height) {
        if (width > MAX_WIDTH) {
          height *= MAX_WIDTH / width;
          width = MAX_WIDTH;
        }
      } else {
        if (height > MAX_HEIGHT) {
          width *= MAX_HEIGHT / height;
          height = MAX_HEIGHT;
        }
      }     

      canvas.width = width;
      canvas.height = height;
      var ctx = canvas.getContext("2d");
      ctx.drawImage(img, 0, 0, width, height);

      var dataurl = canvas.toDataURL("image/jpg");

      $( "#dataurl_image_1" ).val(dataurl);

    });
  } 

  if(typeof this.files[1] !== "undefined") {
    console.log("multiple-2");
    var img = document.createElement("img");
    img.src = window.URL.createObjectURL(this.files[1]);

    $( img ).load(function() {
      console.log("multiple-2-loaded");
      canvas = $("#uploading_canvas_image_2").get(0);                   

      var MAX_WIDTH = 550;
      var MAX_HEIGHT = 400;
      var width = img.width;
      var height = img.height;

      if (width > height) {
        if (width > MAX_WIDTH) {
          height *= MAX_WIDTH / width;
          width = MAX_WIDTH;
        }
      } else {
        if (height > MAX_HEIGHT) {
          width *= MAX_HEIGHT / height;
          height = MAX_HEIGHT;
        }
      }     

      canvas.width = width;
      canvas.height = height;
      var ctx = canvas.getContext("2d");
      ctx.drawImage(img, 0, 0, width, height);

      var dataurl = canvas.toDataURL("image/jpg");

      $( "#dataurl_image_2" ).val(dataurl);

    });
  } 

  if(typeof this.files[2] !== "undefined") {
    console.log("multiple-3");
    var img = document.createElement("img");
    img.src = window.URL.createObjectURL(this.files[2]);

    $( img ).load(function() {
      console.log("multiple-3-loaded");
      canvas = $("#uploading_canvas_image_3").get(0);                   

      var MAX_WIDTH = 550;
      var MAX_HEIGHT = 400;
      var width = img.width;
      var height = img.height;

      if (width > height) {
        if (width > MAX_WIDTH) {
          height *= MAX_WIDTH / width;
          width = MAX_WIDTH;
        }
      } else {
        if (height > MAX_HEIGHT) {
          width *= MAX_HEIGHT / height;
          height = MAX_HEIGHT;
        }
      }     

      canvas.width = width;
      canvas.height = height;
      var ctx = canvas.getContext("2d");
      ctx.drawImage(img, 0, 0, width, height);

      var dataurl = canvas.toDataURL("image/jpg");

      $( "#dataurl_image_3" ).val(dataurl);

    });
  } 

For each image I am checking if it is really there and not undefined. Then it is drawn into the canvas and the corresponding field for dataurl is populated with the dataurl.

The Problem is:

I do not get any errors.

The behaviour is different with different sets of images but its always the same with the same set. For example: I am marking 3 different images in the folder which I want to upload, but always all 3 canvas show the same image (3rd) one also all 3 dataurls are the same.

Sometimes some canvas are blank.

Sometimes it works


It seems like a general problem, but I havent managed to locate why this happens. My guess is it maybe has something to do with the onload function for the image and that the dataurl is created in the same steps. The dataurl itself is insanly long . I am looking at this atm. Maybe someone here has an idea.

I found the issue. The img was causing these problems. Because I always used the same img , eventhough it is in the if condition block . It seems that the function itself is stronger then the if condition?

I had to create a new img variable for every image selected, which means I needed this for image 1:

var img1 = document.createElement("img");
img1.src = window.URL.createObjectURL(this.files[0]);

$( img1 ).load(function() {

//...

ctx.drawImage(img1, 0, 0, width, height);

});

For image 2:

var img2 = document.createElement("img");
img2.src = window.URL.createObjectURL(this.files[1]);

$( img2 ).load(function() {

//...

ctx.drawImage(img2, 0, 0, width, height);

});

For image 3:

var img3 = document.createElement("img");
img3.src = window.URL.createObjectURL(this.files[2]);

$( img3 ).load(function() {

//...

ctx.drawImage(img3, 0, 0, width, height);

});

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM