2017-08-08 180 views
2

我仍然不熟悉這整個畫布的事情,有什麼我有問題,即將圖像內的內容保存爲圖像。這裏是我的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://stackoverflow.com/questions/10673122/how-to-save-canvas-as-an-image-with -canvas-todataurl) –

+0

我已經嘗試過那一個(和許多其他)無濟於事。也許是因爲我的理解還不夠。謝謝你仍然在提醒我。 – nana77

+1

幾個問題:您正在繪製交叉陰影圖像。這會污染你的畫布,阻止它的出口方法。另外,'image.onload'是異步的。這意味着在代碼的同步部分完成執行後,您將實際繪製圖像,這意味着在您調用'toDataURL'時,畫布上仍然沒有畫任何東西。只有在繪製圖像後才能調用導出部分。 – Kaiido

回答

0

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

0

有兩個問題。

第一個是圖像的起源。上的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」找到的。 – Trojan