2010-12-10 119 views
86

我想複製一個畫布的所有內容並將它們轉移到另一個全部在客戶端。我認爲我會使用canvas.toDataURL()context.drawImage()方法來實現這一點,但我遇到了一些問題。如何將一個畫布的內容複製到另一個畫布本地

我的解決方案是獲得Canvas.toDataURL()並將其存儲在Javascript中的Image對象中,然後使用context.drawImage()方法將其放回。

但是,我相信toDataURL方法返回一個64位編碼標籤,其中"data:image/png;base64,"預置了它。這似乎不是一個有效的標記,(我總是可以使用一些正則表達式來刪除這個),但是在子字符串"data:image/png;base64,"之後的64位編碼的字符串是一個有效的圖像嗎?我可以說image.src=iVBORw...ASASDAS,並在畫布上畫回來嗎?

我已經看了一些相關的問題: Display canvas image from one canvas to another canvas using base64

但解決方案似乎並不正確。

回答

191

實際上你根本不需要創建圖像。 drawImage()將接受Canvas以及Image對象。

//grab the context from your destination canvas 
var destCtx = destinationCanvas.getContext('2d'); 

//call its drawImage() function passing it the source canvas directly 
destCtx.drawImage(sourceCanvas, 0, 0); 

方式比使用ImageData對象或Image元件更快。

請注意,sourceCanvas可以是HTMLImageElementHTMLVideoElementHTMLCanvasElement。正如Dave在此回答下面的評論中所述,您的不能使用畫布繪畫上下文作爲源。如果您有一個畫布繪製上下文,而不是從中創建的畫布元素,則在context.canvas下的上下文中存在對原始畫布元素的引用。

這裏是一個jsPerf說明爲什麼這是克隆的畫布的唯一正確途徑:http://jsperf.com/copying-a-canvas-element

-5

我設法得到它的工作,我就是這樣做似乎正確:

testImage = new testImage(); 
testImage.src = data:image/png;base64,iVBORw0KG......kSZIkSZIkSZI0u/1/diDteJCiN80AAAAASUVORK5CYII= 

(上面的網址就是一個例子)

context.drawImage(testImg,0,0); 

這似乎當我在控制檯上運行它的工作Chrome和FireBug

+13

這將工作,但它的crufty,而不是最好的預成型的方式來做到這一點。 – 2011-08-21 22:32:52

+0

這正是我需要的!謝謝! – 2014-07-24 20:33:44

0

@羅伯特 - 赫斯特有一個更簡潔的方法,但這種方法可能在某些地方被用來當你真正想擁有複製後的Data Url的副本。示例:當您構建使用大量圖像/畫布操作的網站時。

// select canvas elements 
    var sourceCanvas = document.getElementsById("some-unique-id"); 
    var destCanvas = document.getElementsByClassName("some-class-selector")[0]; 

    //copy canvas by DataUrl 
    var sourceImageData = sourceCanvas.toDataURL("image/png"); 
    var destCanvasContext = destCanvas.getContext('2d'); 

    var destinationImage = new Image; 
    destinationImage.onload = function(){ 
     destCanvasContext.drawImage(destinationImage,0,0); 
    }; 
    destinationImage.src = sourceImageData; 
相關問題