How to Copy Contents of One Canvas to Another Canvas Locally

J Kao picture J Kao · Dec 10, 2010 · Viewed 116.4k times · Source

I'd like to copy ALL contents of one canvas and transfer them to another all on the client-side. I would think that I would use the canvas.toDataURL() and context.drawImage() method to implement this but I am running into a few issues.

My solution would be to get Canvas.toDataURL() and store this in an Image object in Javascript, and then use the context.drawImage() method to place it back.

However, I believe the toDataURL method returns a 64 bit encoded tag with "data:image/png;base64," prepended to it. This does not seem to be a valid tag, (I could always use some RegEx to remove this), but is that 64 bit encoded string AFTER the "data:image/png;base64," substring a valid image? Can I say image.src=iVBORw...ASASDAS, and draw this back on the canvas?

I've looked at some related issues: Display canvas image from one canvas to another canvas using base64

But the solutions don't appear to be correct.

Answer

Robert Hurst picture Robert Hurst · Aug 22, 2011

Actually you don't have to create an image at all. drawImage() will accept a Canvas as well as an Image object.

//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);

Way faster than using an ImageData object or Image element.

Note that sourceCanvas can be a HTMLImageElement, HTMLVideoElement, or a HTMLCanvasElement. As mentioned by Dave in a comment below this answer, you cannot use a canvas drawing context as your source. If you have a canvas drawing context instead of the canvas element it was created from, there is a reference to the original canvas element on the context under context.canvas.

Here is a jsPerf to demonstrate why this is the only right way to clone a canvas: http://jsperf.com/copying-a-canvas-element