如何将一个画布的内容本地复制到另一个画布


128

我想复制一个画布上的所有内容,然后将它们全部转移到客户端上的所有内容。我想我会使用canvas.toDataURL()and context.drawImage()方法来实现这一点,但是我遇到了一些问题。

我的解决方案是将其获取Canvas.toDataURL()并存储在Javascript中的Image对象中,然后使用该context.drawImage()方法将其放回原处。

但是,我相信该toDataURL方法会返回一个带有64位编码标签的标签"data:image/png;base64,"。这似乎不是一个有效的标签,(我总是可以使用一些RegEx删除它),但是"data:image/png;base64,"子字符串之后的64位编码字符串是否是有效的图像?我可以说image.src=iVBORw...ASASDAS,然后将其画在画布上吗?

我看过一些相关的问题: 使用base64将画布图像从一个画布显示到另一个画布

但是解决方案似乎并不正确。

Answers:


273

实际上,您根本不需要创建图像。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在此答案下方的评论中提到的那样,您不能将canvas绘图上下文用作源。如果您有一个画布绘图上下文而不是其创建的画布元素,则在上下文中有对原始画布元素的引用context.canvas

这是一个jsPerf来演示为什么这是克隆画布的唯一正确方法:http : //jsperf.com/copying-a-canvas-element


66
一小点让我震惊:虽然您可以绘制画布(HTMLCanvasElement),但不能绘制上下文(CanvasRenderingContext2D)。使用myContext.canvas代替。
戴夫

3
@戴夫注释是一个必须阅读 ... woud给予+10如果可能的话)。@ Robert-Hurst必须用此评论补充他的回答,因为他没有指定从何source canvas而来...
Paulo Bueno

你能举个例子吗?
ShibinRagh '16

@RogerGajraj实际上,画布不必是可见的。这在这里得到证明=> jsfiddle.net/d36wwtvj
罗伯特·赫斯特

2

@ robert-hurst使用更干净的方法。

但是,在您真正希望在复制后拥有Data Url副本的地方,也可以使用此解决方案。例如,当您建立一个使用大量图像/画布操作的网站时。

    // select canvas elements
    var sourceCanvas = document.getElementById("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;
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.