22

I wanted to upload the image files, draw them into canvas, make changes and save it in the database. I tried to test the base64 value that the canvas image (Pic) returned, and it is blank. However, I see the result when I append the canvas (Pic) to the document. What am I doing wrong here?

function handleFileSelect(evt) {
  var files = evt.target.files; // FileList object                
  for (var i = 0, f; f = files[i]; i++) {

    if (!f.type.match('image.*')) {
      continue;
    }
    // read contents of files asynchronously
    var reader = new FileReader();

    // Closure to capture the file information.
    reader.onload = (function(theFile) {
      return function(e) {

        var canvas = document.createElement("canvas");

        var datauri = event.target.result,
          ctx = canvas.getContext("2d"),
          img = new Image();

        img.onload = function() {

          canvas.width = width;
          canvas.height = height;
          ctx.drawImage(img, 0, 0, width, height);
        };
        img.src = datauri;
        var imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);

        document.body.appendChild(canvas); //picture gets uploaded                    

        // Generate the image data

        var Pic = canvas.toDataURL("image/png");

        console.log(Pic); // => returns base64 value which when tested equivalent to blank                              
        Pic = Pic.replace(/^data:image\/(png|jpg);base64,/, "")

        // Sending image to Server
        $.ajax({
          // …
        });

      };
    })(f);
    reader.readAsDataURL(f);
  }
}
8
  • 1
    Why is the object parameter of your $.ajax call (which is // Sending image to Server) empty? Please add a comment if you intentionally skipped some lines. Commented Jul 2, 2015 at 19:52
  • 1
    Does console.log(Pic); output anything? Commented Jul 2, 2015 at 19:53
  • yes, it gives some base 64 value which I tested is basically blank: Commented Jul 2, 2015 at 19:55
  • @Xufox: that's not an issue Commented Jul 2, 2015 at 20:00
  • 2
    I think, everything from var imageData = … should go into the img.onload function. The image needs to load in order to draw it to the canvas (which is done correctly) but also, the canvas needs to have the image to get a URL from it. Commented Jul 2, 2015 at 20:26

2 Answers 2

28

My intuition says that everything from var imageData = … should go into the img.onload function.

That means, at the relevant part the code becomes:

img.onload = function() {
  canvas.width = width;
  canvas.height = height;
  ctx.drawImage(img, 0, 0, width, height);

  var imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);

  document.body.appendChild(canvas); //picture gets uploaded                    

  // Generate the image data

  var Pic = canvas.toDataURL("image/png");

  console.log(Pic); // => returns base64 value which when tested equivalent to blank                              
  Pic = Pic.replace(/^data:image\/(png|jpg);base64,/, "")

  // Sending image to Server
  $.ajax({
    // …
  });
};
img.src = datauri;

The reason is that the line

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

correctly executes after the image has been loaded. But unfortunately, you don’t wait for loading when this line gets executed:

var imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);

and all subsequent lines.

The image needs to be loaded in order to draw it on the canvas. The canvas needs to contain the loaded image in order to call getImageData.

Sign up to request clarification or add additional context in comments.

1 Comment

I had so many weird issues by not using the onload function. Using that fixes everything for me. Thanks.
-2

I found a better solution to get the base64 code

Instead of this line:

var Pic = canvas.toDataURL("image/png");

use this:

var Pic = canvas.toDataURL("image/png").split(',')[1];

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.