2010-12-10 116 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; 
相关问题