无法保存图像内
问题描述:
我仍然不熟悉这整个画布的事情,有什么我有问题,即将图像内的内容保存为图像。这里是我的fiddle无法保存图像内<canvas>
var img = new Image();
img.src = 'https://mdn.mozillademos.org/files/5397/rhino.jpg';
var canvas = document.getElementById('canvas');
var ctx = canvas.getContext('2d');
img.onload = function() {
ctx.drawImage(img, 0, 0);
img.style.display = 'none';
};
var link = document.createElement('a');
link.innerHTML = 'Save';
link.href = document.getElementById('canvas').toDataURL();
link.addEventListener('click', function(e) {
link.download = "imagename.png";
}, false);
document.body.appendChild(link);
<canvas id="canvas" width="300" height="300"></canvas>
虽然保存对话框出现就好了,保存的图像是空的,就像它不会捕捉含量可言。
任何帮助表示赞赏,如果伴随着如何/为什么我的代码不起作用,您的代码将会。谢谢。
编辑:忘了链接小提琴我基于here我的代码基础不同的是,小提琴将绘图保存在画布中,而我写的仅仅是从另一个来源保存静态图像。
答
您需要在onload
中设置图像href
,并使用img.crossOrigin = "anonymous"
只是为了避免交叉原点错误。
var img = new Image();
img.crossOrigin = "anonymous";
img.src = 'http://farm5.static.flickr.com/4005/4706825697_c0367e6dee_b.jpg';
var canvas = document.getElementById('canvas');
var ctx = canvas.getContext('2d');
img.onload = function() {
ctx.drawImage(img, 0, 0, 300, 300);
link.href = document.getElementById('canvas').toDataURL();
};
var link = document.createElement('a');
link.innerHTML = 'Save';
//link.href = document.getElementById('canvas').toDataURL();
link.addEventListener('click', function(e) {
link.download = "imagename.png";
}, false);
document.body.appendChild(link);
<canvas id="canvas" width="300" height="300"></canvas>
答
有两个问题。
第一个是图像的起源。上的jsfiddle你会得到一个Uncaught DOMException: Failed to execute 'toDataURL' on 'HTMLCanvasElement': Tainted canvases may not be exported.
- 作为另一个答复中提到,Base64编码的图像,然后设定
img.src = 'data:image/jpeg;base64,/...';
解决了这一问题。 - 另一种解决方案:在本地运行Web服务器,并根据其在服务器上的位置(例如,
img.src = './rhino.jpg';
。
即使在处理完之后,下载的图像也会像以前一样“空”。这是因为你的代码的执行顺序。 link.href = canvas.toDataURL();
在图像的“加载”事件触发之前执行,因此画布为在您设置数据的位置为空。
- 将该行放在
img.onload
函数中可确保链接的下载数据仅在图像加载后才设置。这种方法很方便,因为一旦设置了href
属性(例如悬停时指针,默认带下划线的文本),它就允许<a>
标签以默认行为行为。 - 将该行放置在链接的“单击”事件处理程序中可以顺利运行,但会失去上述默认链接行为。
这里的工作JS的一个例子,假设图像文件是在服务器上:
var img = new Image();
img.src = './rhino.jpg';
var canvas = document.getElementById('canvas');
var ctx = canvas.getContext('2d');
var link = document.createElement('a');
link.innerHTML = 'Save';
img.onload = function() {
ctx.drawImage(img, 0, 0);
img.style.display = 'none';
link.href = canvas.toDataURL();
};
link.addEventListener('click', function(e) {
link.download = "imagename.png";
}, false);
document.body.appendChild(link);
而一个JSFiddle,使用Base-64编码的图像。
可能的重复[如何保存画布作为一个图像与canvas.toDataURL()?](https://*.com/questions/10673122/how-to-save-canvas-as-an-image-with -canvas-todataurl) –
我已经尝试过那一个(和许多其他)无济于事。也许是因为我的理解还不够。谢谢你仍然在提醒我。 – nana77
几个问题:您正在绘制交叉阴影图像。这会污染你的画布,阻止它的出口方法。另外,'image.onload'是异步的。这意味着在代码的同步部分完成执行后,您将实际绘制图像,这意味着在您调用'toDataURL'时,画布上仍然没有画任何东西。只有在绘制图像后才能调用导出部分。 – Kaiido