无法保存图像内

问题描述:

我仍然不熟悉这整个画布的事情,有什么我有问题,即将图像内的内容保存为图像。这里是我的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我的代码基础不同的是,小提琴将绘图保存在画布中,而我写的仅仅是从另一个来源保存静态图像。

+0

可能的重复[如何保存画布作为一个图像与canvas.toDataURL()?](https://*.com/questions/10673122/how-to-save-canvas-as-an-image-with -canvas-todataurl) –

+0

我已经尝试过那一个(和许多其他)无济于事。也许是因为我的理解还不够。谢谢你仍然在提醒我。 – nana77

+1

几个问题:您正在绘制交叉阴影图像。这会污染你的画布,阻止它的出口方法。另外,'image.onload'是异步的。这意味着在代码的同步部分完成执行后,您将实际绘制图像,这意味着在您调用'toDataURL'时,画布上仍然没有画任何东西。只有在绘制图像后才能调用导出部分。 – Kaiido

您需要在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>

+0

好习惯,,解释你的答案 – Durga

+0

@Durga补充说明 –

+0

这实际上适用于你的特定img.src。不知什么时候,当我使用我的图像源'https://mdn.mozillademos.org/files/5397/rhino.jpg'时,它只是...空着。链接:https://jsfiddle.net/9sag2ju7/17/ – nana77

有两个问题。

第一个是图像的起源。上的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编码的图像。

+0

感谢您的回答。不过要问,你如何生成这么长的base-64编码图像? – nana77

+0

我使用了https://www.base64-image.de,它是通过搜索“base 64 encode image”找到的。 – *