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

Posted

技术标签:

【中文标题】如何将一个画布的内容本地复制到另一个画布【英文标题】:How to Copy Contents of One Canvas to Another Canvas Locally 【发布时间】:2011-05-23 06:20:21 【问题描述】:

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

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

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

我查看了一些相关问题: Display canvas image from one canvas to another canvas using base64

但解决方案似乎不正确。

【问题讨论】:

【参考方案1】:

实际上,您根本不必创建图像。 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 可以是 htmlImageElement、HTMLVideoElement 或 HTMLCanvasElement。正如Dave 在此答案下方的评论中所提到的,您不能使用画布绘图上下文作为源。如果您有一个画布绘图上下文而不是创建它的画布元素,则在context.canvas 下的上下文中有对原始画布元素的引用。

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

【讨论】:

一个让我大吃一惊的小问题:虽然您可以绘制画布 (HTMLCanvasElement),但您不能绘制上下文 (CanvasRenderingContext2D)。请改用myContext.canvas @Dave 评论是必读...如果可能的话,我会给出+10 ;)。 @Robert-Hurst 必须用这条评论补充他的答案,因为他没有指定 source canvas 来自哪里...... 您能举个例子吗? @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;

【讨论】:

我需要复制画布的内容以在其他地方使用 - 这非常完美,因为它生成了大约 80KB 的数据,而使用 getImageData 生成了大约 60MB 的数据

以上是关于如何将一个画布的内容本地复制到另一个画布的主要内容,如果未能解决你的问题,请参考以下文章

如何从具有所有属性的页面复制canvas元素?

是否可以将画布图像复制到剪贴板?

如何有选择地将一个函数中的所有画布动作转移到另一个函数

我如何清除画布? [复制]

将画布复制到 p5.js 中的图形对象

如何在不复制的情况下将画布 imageData 传递给 emscripten c++ 程序?