合并多个画布并下载为图像

Ale*_*ani 4 html javascript canvas html5-canvas todataurl

我试图将两个 HTML 画布合并到一个画布中,然后将其下载为图像。我的代码如下:

function downloadCanvas() {
    var bottleCanvas = document.getElementById('bottleCanvas');
    var designCanvas = document.getElementById('editorCanvas');

    var bottleContext = bottleCanvas.getContext('2d');
    bottleContext.drawImage(designCanvas, 69, 50);

    var dataURL = bottleCanvas.toDataURL("image/png");
    var link = document.createElement('a');
    link.download = "bottle-design.png";
    link.href = bottleCanvas.toDataURL("image/png").replace("image/png", "image/octet-stream");
    link.click();
}
Run Code Online (Sandbox Code Playgroud)

我的问题似乎是以下几行:

bottleContext.drawImage(designCanvas, 69, 50);
Run Code Online (Sandbox Code Playgroud)

这应该将一个画布的内容绘制到另一个画布上,它确实这样做了,但随后会阻止代码的后一部分运行和下载图像。当我删除此特定行时,下载功能工作正常,但不幸的是只下载其中一个画布。

因此,我的问题是:我在这里做错了什么?或如何合并两个 HTML 画布,然后将其下载为图像。

(另外,我上面的下载代码仅适用于 Chrome - 在其他浏览器中,我无法设置文件名和文件扩展名。)

mar*_*rkE 6

您可能会遇到因将跨域来源的图像绘制到画布上而导致的安全错误。在任何画布上绘制跨域图像将“污染”该画布,context.toDataURL如果您尝试执行toDataURL. 如果您将受污染的画布绘制到未受污染的画布上,则会发生同样的“污染”。

解决方法是确保您在画布上绘制的所有图像都来自与您的网页相同的域。

以下是您的代码在使用不会引发跨域安全错误的图像时正常工作的示例:

var img=new Image();
img.crossOrigin='anonymous';
img.onload=start;
img.src="https://dl.dropboxusercontent.com/u/139992952/multple/fish.jpg";
function start(){

  var bottleCanvas = document.getElementById('bottleCanvas');
  var designCanvas = document.getElementById('editorCanvas');
  var ctxb=bottleCanvas.getContext('2d');
  var ctxd=editorCanvas.getContext('2d');

  ctxb.drawImage(img,0,0);
  ctxd.fillRect(50,50,50,50);

  downloadCanvas();
}

function downloadCanvas() {
  var bottleCanvas = document.getElementById('bottleCanvas');
  var designCanvas = document.getElementById('editorCanvas');

  var bottleContext = bottleCanvas.getContext('2d');
  bottleContext.drawImage(designCanvas, 69, 50);

  var dataURL = bottleCanvas.toDataURL("image/png");
  var link = document.createElement('a');
  link.download = "bottle-design.png";
  link.href = bottleCanvas.toDataURL("image/png").replace("image/png", "image/octet-stream");
  link.click();
}
Run Code Online (Sandbox Code Playgroud)
body{ background-color: ivory; }
canvas{border:1px solid red;}
Run Code Online (Sandbox Code Playgroud)
<canvas id="bottleCanvas" width=300 height=300></canvas>
<canvas id="editorCanvas" width=300 height=300></canvas>
Run Code Online (Sandbox Code Playgroud)

满足跨域安全限制

您可以将图像托管在已经允许对其图像进行跨源访问的服务器上。这就是我在上面的例子中所做的。Dropbox.com 允许您指定可以将其托管的图像绘制到画布上,而不会“污染”该画布。

您还可以配置您的 S3 存储桶以允许对您的图像进行跨源访问。此链接提供了有关如何将响应标头设置为服务器跨域图像的说明:http : //docs.aws.amazon.com/AmazonS3/latest/dev/cors.html

请注意,在我的示例中,如果您使用的是跨域图像,则您还必须image.crossOrigin='anonymous'在最初在 javascript 中创建图像对象时设置该标志。