简体   繁体   English

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

[英]How to wait for the multiple images to load in the canvas and convert to base64?

I'm trying to get a base64 version of a canvas in HTML5. 我正在尝试在HTML5中获得画布的base64版本。

Currently, the base64 image that I get from the canvas is blank. 目前,我从画布上获得的base64图像为空白。

I have found similar questions for example this one: 我发现类似的问题,例如这个问题:

HTML Canvas image to Base64 problem HTML Canvas图像到Base64问题

However, the issue that I have is that because I am adding 2 images in the canvas, I cannot use the example provided in those answers as most of them are using single image. 但是,我的问题是,因为我要在画布中添加2张图像,所以我无法使用这些答案中提供的示例,因为它们中的大多数都使用单个图像。

I understand that I have to wait until the canvas image is loaded properly before trying to get the base64 image. 我知道我必须等到画布图像正确加载后才能尝试获取base64图像。 But I don't know how in my case. 但是我不知道该怎么办。

This is my code: 这是我的代码:

 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> 

and this is a working FIDDLE: 这是可行的FIDDLE:

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

Can someone please advice on this issue? 有人可以在这个问题上提出建议吗?

Thanks in advance. 提前致谢。

EDIT: 编辑:

As suggested in the comments bellow, i tried to use a counter and when the counter reaches a specific number, I convert the canvas to base64. 如下面的注释中所建议,我尝试使用一个计数器,当计数器达到特定数字时,我将画布转换为base64。

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

In both your examples (the one from the question and the one from the comments), the order of commands does not really respect the async nature of the task at hand. 在您的两个示例(一个来自问题的示例和一个来自注释的示例)中,命令的顺序并没有真正尊重手头任务的异步性质。 In your later example, you should put the if( count == 2 ) block inside the onload callbacks to make it work. 在后面的示例中,应将if( count == 2 )块放入onload回调中,以使其正常工作。

However, even then you will run into the next problem: You are loading the images from different domains. 但是,即使那样,您仍然会遇到下一个问题:您正在从不同的域加载图像。 You can still draw them (either into the canvas or using an <img> tag), but you are not able to access their contents directly. 您仍然可以绘制它们(在画布中或使用<img>标记),但是您不能直接访问它们的内容。 Not even with the detour of using the <canvas> element. 即使使用<canvas>元素也不走弯路。

I changed to code so it would work, if the images are hosted on the same domain. 我将代码更改为如果图像托管在同一域上则可以运行。 I also used a function to load the image and promises to handle the callbacks. 我还使用了一个函数来加载图像并承诺处理回调。 The direct way of using callbacks and a counting variable, seem error-prone to me. 使用回调和计数变量的直接方法对我来说似乎容易出错。 If you check out the respective fiddle , you will notice the SecurityError shown. 如果您查看相应的小提琴 ,您将注意到显示的SecurityError This is the result of the aforementioned problem with the Same-Origin-Policy I mentioned. 这是我提到的相同原产地政策的上述问题的结果。

A previous question of mine in a similar direction was about how to detect, if I can still read the contents of a <canvas> after adding some images. 以前在类似方向上的问题是关于如何检测,如果我在添加一些图像后仍能读取<canvas>的内容。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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