Como copiar o conteúdo de uma tela para outra tela localmente


129

Eu gostaria de copiar TODOS os conteúdos de uma tela e transferi-los para outra no lado do cliente. Eu pensaria que usaria o método canvas.toDataURL()e context.drawImage()para implementar isso, mas estou tendo alguns problemas.

Minha solução seria obter Canvas.toDataURL()e armazenar isso em um objeto Image em Javascript e, em seguida, use o context.drawImage()método para colocá-lo de volta.

No entanto, acredito que o toDataURLmétodo retorne uma tag codificada de 64 bits com "data:image/png;base64,"anexada a ela. Isso não parece ser uma marca válida (eu sempre poderia usar algum RegEx para remover isso), mas será que a string codificada de 64 bits APÓS a "data:image/png;base64,"substring é uma imagem válida? Posso dizer image.src=iVBORw...ASASDASe desenhar isso de volta na tela?

Analisei alguns problemas relacionados: Exibir imagem de tela de uma tela para outra tela usando base64

Mas as soluções não parecem estar corretas.

Respostas:


273

Na verdade, você não precisa criar uma imagem. drawImage()aceitará um objeto e Canvasum 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);

Muito mais rápido do que usar um ImageDataobjeto ou Imageelemento.

Observe que sourceCanvaspode ser um HTMLImageElement , HTMLVideoElement ou HTMLCanvasElement . Conforme mencionado por Dave em um comentário abaixo desta resposta, você não pode usar um contexto de desenho de tela como sua fonte . Se você tiver um contexto de desenho de tela em vez do elemento de tela a partir do qual ele foi criado, há uma referência ao elemento de tela original no contexto abaixo context.canvas.

Aqui está um jsPerf para demonstrar por que essa é a única maneira correta de clonar uma tela: http://jsperf.com/copying-a-canvas-element


66
um pequeno ponto que me tropeçou: enquanto você pode desenhar uma tela ( HTMLCanvasElement), você não pode desenhar um contexto ( CanvasRenderingContext2D). Use em myContext.canvasvez disso.
21413 Dave

3
Comentário @Dave é DEVE LER ... woud dar 10, se possível;). @ Robert-Hurst deve complementar a sua resposta com este comentário desde que ele não especifica de onde source canvasvem ...
Paulo Bueno

Você poderia fornecer um exemplo?
ShibinRagh 3/09/16

@RogerGajraj Na verdade, a tela não precisa estar visível. Isto é demonstrado lá => jsfiddle.net/d36wwtvj
Robert Hurst

2

@ robert-hurst tem uma abordagem mais limpa.

No entanto, essa solução também pode ser usada em locais em que você deseja obter uma cópia do URL de dados após a cópia. Por exemplo, quando você está construindo um site que usa muitas operações de imagem / tela.

    // 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;
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.