4

I'm attempting to merge two HTML canvases into a single canvas and then download that as an image. My code is as below:

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

My problem here seems to be the following line:

bottleContext.drawImage(designCanvas, 69, 50);

This is supposed to draw the contents of one canvas onto the other, which it does, but then prevents the latter part of the code from running and downloading the image. When I remove this particular line the download function works fine, but unfortunately only downloads one of the canvases.

My question therefore is either: What am I doing wrong here? or How would I merge two HTML canvases and then download it as an image.

(On another note, my above code for downloading only works well in Chrome - in other browsers I am unable to set the name of the file and set the file extension.)

4

1 回答 1

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();
}
body{ background-color: ivory; }
canvas{border:1px solid red;}
<canvas id="bottleCanvas" width=300 height=300></canvas>
<canvas id="editorCanvas" width=300 height=300></canvas>

满足跨域安全限制

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

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

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

于 2015-04-10T01:45:19.033 回答