合并多个画布并下载为图像
Merge Multiple Canvases and Download as Image
我正在尝试将两个 HTML canvas 合并为一个 canvas,然后将其作为图像下载。我的代码如下:
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();
}
我的问题似乎是以下一行:
bottleContext.drawImage(designCanvas, 69, 50);
这应该将一个 canvas 的内容绘制到另一个上,它确实这样做了,但随后阻止了代码的后半部分 运行 和下载图像。当我删除此特定行时,下载功能工作正常,但不幸的是只下载了 canvases.
之一
因此我的问题是:我在这里做错了什么?或者我如何合并两个 HTML canvases 然后将其下载为图像。
(另外请注意,我上面的下载代码仅在 Chrome 中运行良好 - 在其他浏览器中我无法设置文件名和文件扩展名。)
您可能遇到了一个安全错误,这是因为将来源为 cross-domain 的图像绘制到您的 canvas 上。在任何 canvas 上绘制 cross-domain 图像将 "taint" canvas 并且不允许 context.toDataURL
并在您尝试执行 toDataURL
时引发安全错误。如果将受污染的 canvas 绘制到 non-contaminated canvas.
上,也会发生同样的 "tainting"
解决方法是确保您在 canvas 上绘制的所有图像都来自与您的网页相同的域。
这是您的代码在使用未引发 cross-domain 安全错误的图像时正常工作的示例:
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>
满足cross-origin安全限制
您可以将图像托管在已经允许 cross-origin 访问其图像的服务器上。这就是我在上面的示例中所做的。 Dropbox.com 允许您指定它承载的图像可以绘制到 canvas 而不是 "tainting" canvas.
您还可以配置 S3 存储桶以允许 cross-origin 访问您的图像。此 link 提供了有关如何设置对服务器 cross-origin 图像的响应 headers 的说明:http://docs.aws.amazon.com/AmazonS3/latest/dev/cors.html
请注意,在我的示例中,如果您使用 cross-origin 图像,则在 [=63] 中最初创建图像 object 时,还必须设置 image.crossOrigin='anonymous'
标志=].
我正在尝试将两个 HTML canvas 合并为一个 canvas,然后将其作为图像下载。我的代码如下:
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();
}
我的问题似乎是以下一行:
bottleContext.drawImage(designCanvas, 69, 50);
这应该将一个 canvas 的内容绘制到另一个上,它确实这样做了,但随后阻止了代码的后半部分 运行 和下载图像。当我删除此特定行时,下载功能工作正常,但不幸的是只下载了 canvases.
之一因此我的问题是:我在这里做错了什么?或者我如何合并两个 HTML canvases 然后将其下载为图像。
(另外请注意,我上面的下载代码仅在 Chrome 中运行良好 - 在其他浏览器中我无法设置文件名和文件扩展名。)
您可能遇到了一个安全错误,这是因为将来源为 cross-domain 的图像绘制到您的 canvas 上。在任何 canvas 上绘制 cross-domain 图像将 "taint" canvas 并且不允许 context.toDataURL
并在您尝试执行 toDataURL
时引发安全错误。如果将受污染的 canvas 绘制到 non-contaminated canvas.
解决方法是确保您在 canvas 上绘制的所有图像都来自与您的网页相同的域。
这是您的代码在使用未引发 cross-domain 安全错误的图像时正常工作的示例:
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>
满足cross-origin安全限制
您可以将图像托管在已经允许 cross-origin 访问其图像的服务器上。这就是我在上面的示例中所做的。 Dropbox.com 允许您指定它承载的图像可以绘制到 canvas 而不是 "tainting" canvas.
您还可以配置 S3 存储桶以允许 cross-origin 访问您的图像。此 link 提供了有关如何设置对服务器 cross-origin 图像的响应 headers 的说明:http://docs.aws.amazon.com/AmazonS3/latest/dev/cors.html
请注意,在我的示例中,如果您使用 cross-origin 图像,则在 [=63] 中最初创建图像 object 时,还必须设置 image.crossOrigin='anonymous'
标志=].