So kopieren Sie den Inhalt einer Leinwand lokal auf eine andere Leinwand

128

Ich möchte ALLE Inhalte einer Zeichenfläche kopieren und auf der Clientseite auf eine andere übertragen. Ich würde denken, dass ich die Methode canvas.toDataURL()und context.drawImage()verwenden würde, um dies zu implementieren, aber ich stoße auf einige Probleme.

Meine Lösung wäre, Canvas.toDataURL()dies in einem Image-Objekt in Javascript abzurufen und zu speichern und es dann mithilfe der context.drawImage()Methode wieder zu platzieren.

Ich glaube jedoch, dass die toDataURLMethode ein 64-Bit-codiertes Tag mit "data:image/png;base64,"vorangestelltem Tag zurückgibt . Dies scheint kein gültiges Tag zu sein (ich könnte immer etwas RegEx verwenden, um dies zu entfernen), aber ist diese 64-Bit-codierte Zeichenfolge NACH dem "data:image/png;base64,"Teilstring ein gültiges Bild? Kann ich das sagen image.src=iVBORw...ASASDASund auf die Leinwand zurückziehen?

Ich habe mir einige verwandte Probleme angesehen: Anzeigen von Leinwandbildern von einer Leinwand auf eine andere Leinwand mit base64

Die Lösungen scheinen jedoch nicht korrekt zu sein.

J Kao
quelle

Antworten:

273

Eigentlich müssen Sie überhaupt kein Bild erstellen. drawImage()akzeptiert sowohl ein Canvasals auch ein ImageObjekt.

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

Viel schneller als mit einem ImageDataObjekt oder ImageElement.

Beachten Sie, dass sourceCanvasein sein kann HTMLImageElement , HTMLVideoElement oder ein HTMLCanvasElement . Wie von Dave in einem Kommentar unter dieser Antwort erwähnt, können Sie keinen Canvas-Zeichnungskontext als Quelle verwenden . Wenn Sie anstelle des Canvas-Elements, aus dem es erstellt wurde, einen Canvas-Zeichnungskontext haben, befindet sich im Kontext unter ein Verweis auf das ursprüngliche Canvas-Element context.canvas.

Hier ist ein jsPerf, um zu demonstrieren, warum dies der einzig richtige Weg ist, eine Zeichenfläche zu klonen: http://jsperf.com/copying-a-canvas-element

Robert Hurst
quelle
66
Ein kleiner Punkt, der mich auslöste: Während Sie eine Leinwand zeichnen können ( HTMLCanvasElement), können Sie keinen Kontext zeichnen ( CanvasRenderingContext2D). Verwenden Sie myContext.canvasstattdessen.
Dave
3
@ Dave Kommentar ist ein MUSS LESEN ... würde wenn möglich +10 geben;). @ Robert-Hurst muss seine Antwort mit diesem Kommentar ergänzen, da er nicht angibt, woher er source canvaskommt ...
Paulo Bueno
Könnten Sie bitte ein Beispiel nennen?
ShibinRagh
@ RogerGajraj Eigentlich muss die Leinwand nicht sichtbar sein. Dies wird dort demonstriert => jsfiddle.net/d36wwtvj
Robert Hurst
2

@ Robert-Hurst hat einen saubereren Ansatz.

Diese Lösung kann jedoch auch an Orten verwendet werden, an denen Sie nach dem Kopieren tatsächlich eine Kopie der Daten-URL haben möchten. Zum Beispiel, wenn Sie eine Website erstellen, die viele Bild- / Zeichenflächenoperationen verwendet.

    // 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;
vishwarajanand
quelle