HTML5画布的toDataURL返回空白

19

我希望上传图像文件,将其绘制到画布上,进行更改并将其保存在数据库中。 我试图测试画布图像 (Pic) 返回的 base64 值,但它是空白的。 然而,当我将画布 (Pic) 添加到文档中时,我可以看到结果。 我在这里做错了什么?

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);
  }
}

1
为什么您的 $.ajax 调用的对象参数(即 // Sending image to Server)为空?如果您有意跳过某些行,请添加注释。 - Tobias
1
console.log(Pic); 输出了什么? - hindmost
@Xufox:这不是个问题。 - user3399326
你为什么在“Pic”上应用replace()?不能在服务器上处理吗? - hindmost
2
我认为,从var imageData = ...开始的所有内容都应该放在img.onload函数中。图像需要加载才能将其绘制到画布上(这一点已经做得很好),但是画布还需要从图像中获取URL。 - Sebastian Simon
显示剩余3条评论
2个回答

27

我的直觉告诉我,从var imageData = …开始的所有内容应该放在img.onload函数中。

也就是说,在相关部分代码变成了:

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;

原因是这条线

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

在图像加载完成后正确执行。但不幸的是,当执行这行代码时,您没有等待加载:

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

以及之后的所有行。

为了在画布上绘制图像,需要先加载图像。为了调用getImageData,画布需要包含已加载的图像。


-1

我找到了一个更好的方法来获取base64代码

不要使用这行代码:

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

使用这个:
var Pic = canvas.toDataURL("image/png").split(',')[1];

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接