HTML5 Canvas toDataURL vuelve en blanco

Resuelto user3399326 asked hace 9 años • 2 respuestas

Quería cargar los archivos de imagen, dibujarlos en el lienzo, realizar cambios y guardarlos en la base de datos. Intenté probar el valor base64 que Picdevolvió la imagen del lienzo () y está en blanco. Sin embargo, veo el resultado cuando agrego el lienzo ( Pic) al documento. ¿Qué estoy haciendo mal aquí?

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);
  }
}
user3399326 avatar Jul 03 '15 02:07 user3399326
Aceptado

Mi intuición dice que todo var imageData = …debe ir a la img.onloadfunción.

Eso significa que, en la parte relevante, el código se convierte en:

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;

La razón es que la línea

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

se ejecuta correctamente después de cargar la imagen. Pero desafortunadamente, no esperas a que se cargue cuando se ejecuta esta línea:

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

y todas las líneas posteriores.

Es necesario cargar la imagen para poder dibujarla en el lienzo. El lienzo debe contener la imagen cargada para poder llamar getImageData.

Sebastian Simon avatar Jul 02 '2015 20:07 Sebastian Simon