问题描述
我正在尝试将两个HTML画布合并到一个画布中,然后将其作为图像下载。我的代码如下:
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.
因此,我的问题是:我在这里做错了什么?或者我如何合并两个HTML画布然后将其作为图像下载。
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.
(另一方面,我上面的下载代码仅适用于Chrome - 在其他浏览器中我无法设置文件的名称并设置文件扩展名。)
(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.)
推荐答案
您可能遇到过通过将源为跨域的图像绘制到画布上而导致的安全错误。在任何画布上绘制跨域图像将污染该画布并禁止 context.toDataURL
并在尝试执行 toDataURL时引发安全性错误
。如果您将受污染的画布绘制到未受污染的画布上,则会发生同样的污染。
You are likely encountering a security error caused 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.
修复是为了确保您在画布上绘制的所有图像都来自与您的网页相同的域。
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>
满足跨域安全限制
您可以将图像托管在已允许跨源访问其图像的服务器上。这就是我在上面的例子中所做的。 Dropbox.com允许您指定它所托管的图像可以绘制到画布而不会污染该画布。
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.
您还可以配置S3存储桶以允许交叉原始访问您的图像。此链接提供有关如何将响应标头设置为服务器跨源映像的说明:
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
请注意,如我的例子所示,如果你在使用跨源图像时,您还必须在最初使用javascript创建图像对象时设置 image.crossOrigin ='anonymous'
标记。
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.
这篇关于合并多个画布并下载为图像的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!