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

J K*_*Kao 116 html5 canvas

我想复制一个画布的所有内容并将它们转移到客户端的所有内容.我认为我会使用canvas.toDataURL()context.drawImage()方法来实现这个,但我遇到了一些问题.

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

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

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

但解决方案似乎不正确.

Rob*_*rst 251

实际上你根本不需要创建一个图像.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);
Run Code Online (Sandbox Code Playgroud)

比使用ImageData对象或Image元素更快.

请注意,它sourceCanvas可以是HTMLImageElement,HTMLVideoElementHTMLCanvasElement.正如Dave在本答案下面的评论中所提到的,您不能使用画布绘图上下文作为源.如果您有一个画布绘制上下文而不是从中创建的canvas元素,则会在上下文中引用原始canvas元素context.canvas.

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

  • 绊倒我的一个小点:虽然你可以画一个画布(`HTMLCanvasElement`),你*不能*画一个上下文(`CanvasRenderingContext2D`).请改用"myContext.canvas". (59认同)
  • @Dave注释是“必读” ...如果可能,请给+10;)。@ Robert-Hurst必须用此评论补充他的答案,因为他没有指定“源画布”来自何处... (2认同)

vis*_*and 8

@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;
Run Code Online (Sandbox Code Playgroud)