javascript 合并多个画布并下载为图像
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/29551841/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Merge Multiple Canvases and Download as Image
提问by Alex Saidani
I'm attempting to merge two HTML canvases into a single canvas and then download that as an image. My code is as below:
我试图将两个 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();
}
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.
因此,我的问题是:我在这里做错了什么?或如何合并两个 HTML 画布,然后将其下载为图像。
(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.)
(另外,我上面的下载代码仅适用于 Chrome - 在其他浏览器中,我无法设置文件名和文件扩展名。)
采纳答案by markE
You are likely encountering a security errorcaused by drawing an image whose source is cross-domain onto your canvas. Drawing a cross-domain image onto any canvas will "taint" that canvas and disallow context.toDataURL
and raise a security error if you attempt to execute toDataURL
. This same "tainting" will occur if you drawImage a contaminated canvas onto a non-contaminated canvas.
您很可能会遇到因在画布上绘制来源为跨域的图像而导致的安全错误。在任何画布上绘制跨域图像将“污染”该画布,context.toDataURL
如果您尝试执行toDataURL
. 如果您将受污染的画布绘制到未受污染的画布上,则会发生同样的“污染”。
The fix is to make sure all images you draw on the canvas originate on the same domain as your webpage.
解决方法是确保您在画布上绘制的所有图像都来自与您的网页相同的域。
Here is an example of your code working properly when using an image that does not raise the cross-domain security error:
以下是您的代码在使用不会引发跨域安全错误的图像时正常工作的示例:
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>
Satisfying cross-origin security restrictions
满足跨域安全限制
You can host your image on a server that already allows cross-origin access to it's images. That's what I do in my example above. Dropbox.com allows you to specify that an image it hosts may be drawn to canvas without "tainting" that canvas.
您可以将图像托管在已经允许对其图像进行跨源访问的服务器上。这就是我在上面的例子中所做的。Dropbox.com 允许您指定可以将其托管的图像绘制到画布上,而不会“污染”该画布。
You can also configure your S3 bucket to allow cross-origin access to your images. This link provides instructions on how to set the response headers to server cross-origin images: http://docs.aws.amazon.com/AmazonS3/latest/dev/cors.html
您还可以配置您的 S3 存储桶以允许对您的图像进行跨源访问。此链接提供了有关如何将响应标头设置为服务器跨域图像的说明:http: //docs.aws.amazon.com/AmazonS3/latest/dev/cors.html
Note that as in my example, if you're using cross-origin images, you must also set the image.crossOrigin='anonymous'
flag when you initially create the image object in javascript.
请注意,在我的示例中,如果您使用的是跨域图像,则您还必须image.crossOrigin='anonymous'
在最初在 javascript 中创建图像对象时设置该标志。