如何等待多个图像加载到画布并转换为base64?

时间:2017-12-03 20:02:21

标签: javascript jquery html5 canvas

我试图在HTML5中获得base64版本的画布。

目前,我从画布获取的base64图像是空白的。

我发现了类似的问题,例如:

HTML Canvas image to Base64 problem

但是,我遇到的问题是因为我在画布中添加了2个图像,所以我不能使用这些答案中提供的示例,因为大多数图像都使用单个图像。

据我所知,在尝试获取base64图像之前,我必须等到画布图像正确加载。但我不知道我的情况如何。

这是我的代码:



var canvas = document.getElementById('myCanvas');
      var context = canvas.getContext('2d');
  	  context.canvas.width = 1000;
      context.canvas.height = 1000;




var imageObj1 = new Image();

  imageObj1.src = "http://www.offthegridnews.com/wp-content/uploads/2017/01/selfie-psuDOTedu.jpg";
  imageObj1.onload = function() {
    context.drawImage(imageObj1, 0, 180, canvas.width, canvas.height);
  };

var imageObj2 = new Image();


  imageObj2.src = "http://www.publicdomainpictures.net/pictures/150000/velka/banner-header-tapete-145002399028x.jpg"
  imageObj2.onload = function() {
    context.drawImage(imageObj2, 0, 0, canvas.width, 180);
  };
  
// get png data url
//var pngUrl = canvas.toDataURL();
  
var pngUrl = canvas.toDataURL('image/png');

// get jpeg data url 
 var jpegUrl = canvas.toDataURL('image/jpeg');


$('#base').val(pngUrl);

        <div class="contents" style="overflow-x:hidden; overflow-y:scroll;">


            <div style="width:100%; height:90%;">

            <canvas id="myCanvas" class="snap" style="width:100%; height:100%;" onclick="takephoto()"></canvas>


            </div>		
			
        </div>
        
        
        
        <p>
        This is the base64 image
        </p>
        
        <textarea id="base">
        
        
        </textarea>
&#13;
&#13;
&#13;

这是一个有效的FIDDLE:

https://jsfiddle.net/3p3e6Ldu/1/

有人可以就此问题提出建议吗?

提前致谢。

编辑:

正如下面的评论所示,我试图使用计数器,当计数器达到特定数字时,我将画布转换为base64。

像这样:https://jsfiddle.net/3p3e6Ldu/4/

1 个答案:

答案 0 :(得分:3)

在你的两个例子中(问题中的一个和评论中的一个),命令的顺序并不真正尊重手头任务的异步性质。 在后面的示例中,您应该将if( count == 2 )块放在onload回调中以使其正常工作。

然而,即便如此,您仍会遇到下一个问题:您正在加载来自不同域的图像。您仍然可以绘制它们(无论是在画布中还是使用<img>标记),但您无法直接访问它们的内容。甚至没有绕过使用<canvas>元素。

如果图像托管在同一个域中,我就更改为代码以便它可以工作。我还使用了一个函数来加载图像并承诺处理回调。使用回调和计数变量的直接方式对我来说似乎容易出错。如果您查看相应的fiddle,您会看到显示SecurityError。这是我提到的Same-Origin-Policy上述问题的结果。

如果我在添加一些图像后仍然可以读取<canvas>的内容,那么类似方向的previous question是关于如何检测的。

const canvas = document.getElementById('myCanvas');
const context = canvas.getContext('2d');
context.canvas.width = 1000;
context.canvas.height = 1000;

// function to retrieve an image
function loadImage(url) {
  return new Promise((fulfill, reject) => {
    let imageObj = new Image();
    imageObj.onload = () => fulfill(imageObj);
    imageObj.src = url;
  });
}

// get images
Promise.all([
    loadImage("http://www.offthegridnews.com/wp-content/uploads/2017/01/selfie-psuDOTedu.jpg"),
    loadImage("http://www.publicdomainpictures.net/pictures/150000/velka/banner-header-tapete-145002399028x.jpg"),
  ])
  .then((images) => {
    // draw images to canvas
    context.drawImage(images[0], 0, 180, canvas.width, canvas.height);
    context.drawImage(images[1], 0, 0, canvas.width, 180);

    // export to png/jpg
    const pngUrl = canvas.toDataURL('image/png');
    const jpegUrl = canvas.toDataURL('image/jpeg');

    // show in textarea
    $('#base').val(pngUrl);
  })
  .catch( (e) => alert(e) );