Come copiare localmente il contenuto di una tela su un'altra tela


129

Vorrei copiare TUTTI i contenuti di una tela e trasferirli su un altro tutto sul lato client. Penso che utilizzerei il metodo canvas.toDataURL()e context.drawImage()per implementarlo, ma sto riscontrando alcuni problemi.

La mia soluzione sarebbe quella di ottenere Canvas.toDataURL()e memorizzare questo in un oggetto Image in Javascript, quindi utilizzare il context.drawImage()metodo per rimetterlo.

Tuttavia, credo che il toDataURLmetodo restituisca un tag codificato a 64 bit con "data:image/png;base64,"anteposto. Questo non sembra essere un tag valido, (potrei sempre usare un po 'di RegEx per rimuoverlo), ma quella stringa codificata a 64 bit DOPO la "data:image/png;base64,"sottostringa è un'immagine valida? Posso dirlo image.src=iVBORw...ASASDASe riportarlo sulla tela?

Ho esaminato alcuni problemi correlati: Visualizza l'immagine della tela da una tela a un'altra tela utilizzando base64

Ma le soluzioni non sembrano essere corrette.

Risposte:


273

In realtà non devi creare affatto un'immagine. drawImage()accetterà Canvassia un Imageoggetto.

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

Molto più veloce che usare un ImageDataoggetto o un Imageelemento.

Tieni presente che sourceCanvaspuò essere un HTMLImageElement , HTMLVideoElement o un HTMLCanvasElement . Come accennato da Dave in un commento sotto questa risposta, non è possibile utilizzare un contesto di disegno su tela come fonte . Se hai un contesto di disegno su tela invece dell'elemento tela da cui è stato creato, c'è un riferimento all'elemento tela originale nel contesto sotto context.canvas.

Ecco un jsPerf per dimostrare perché questo è l'unico modo giusto per clonare una tela: http://jsperf.com/copying-a-canvas-element


66
un piccolo punto che mi ha fatto inciampare: mentre puoi disegnare una tela ( HTMLCanvasElement), non puoi disegnare un contesto ( CanvasRenderingContext2D). Usa myContext.canvasinvece.
Dave

3
Il commento di @Dave è da LEGGERE ... se possibile darei +10;). @ Robert-Hurst deve completare la sua risposta con questo commento poiché non specifica da dove source canvasviene ...
Paulo Bueno

Potresti fornire un esempio?
ShibinRagh

@RogerGajraj In realtà la tela non deve essere visibile. Questo è dimostrato lì => jsfiddle.net/d36wwtvj
Robert Hurst,

2

@ robert-hurst ha un approccio più pulito.

Tuttavia, questa soluzione può essere utilizzata anche in luoghi in cui si desidera effettivamente avere una copia di Data Url dopo la copia. Ad esempio, quando si crea un sito Web che utilizza molte operazioni di immagine / 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;
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.