2010-12-10 25 views
86

Je souhaite copier TOUS les contenus d'un canevas et les transférer à un autre côté client. Je pense que j'utiliserais la méthode canvas.toDataURL() et context.drawImage() pour implémenter ceci mais je me heurte à quelques problèmes.Comment copier le contenu d'un canevas sur un autre canevas en local

Ma solution serait d'obtenir Canvas.toDataURL() et de le stocker dans un objet Image en Javascript, puis d'utiliser la méthode context.drawImage() pour le replacer.

Cependant, je crois que la méthode toDataURL renvoie un tag codé 64 bits avec "data:image/png;base64," ajouté. Cela ne semble pas être une balise valide, (je pourrais toujours utiliser certains RegEx pour supprimer ceci), mais est-ce que la chaîne encodée en 64 bits APRÈS le "data:image/png;base64," soustrait une image valide? Puis-je dire image.src=iVBORw...ASASDAS, et dessiner ce retour sur la toile?

J'ai regardé quelques questions connexes: Display canvas image from one canvas to another canvas using base64

Mais les solutions ne semblent pas être correct.

Répondre

191

En fait, vous n'avez pas besoin de créer d'image du tout. drawImage() acceptera un Canvas ainsi qu'un objet 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); 

façon plus rapide que d'utiliser un objet ou un élément ImageDataImage. Notez que sourceCanvas peut être un HTMLImageElement, HTMLVideoElement ou un HTMLCanvasElement. Comme mentionné par Dave dans un commentaire ci-dessous cette réponse, vous ne pouvez pas utiliser un contexte de dessin de toile comme source. Si vous disposez d'un contexte de dessin de canevas au lieu de l'élément de canevas à partir duquel il a été créé, il existe une référence à l'élément canevas d'origine dans le contexte sous context.canvas.

Voici un jsPerf pour démontrer pourquoi est-ce la seule bonne façon de cloner une toile: http://jsperf.com/copying-a-canvas-element

+36

un petit point qui m'a fait trébucher: alors que vous pouvez dessiner une toile ('HTMLCanvasElement'), vous * ne pouvez pas * dessiner un contexte (' CanvasRenderingContext2D'). Utilisez 'myContext.canvas' à la place. – Dave

+1

Commentaire @Dave est un ** DOIT LIRE ** ... woud donner +10 si possible;). @ Robert-Hurst doit compléter sa réponse par ce commentaire car il ne précise pas d'où vient le 'source canvas' ... –

+0

Pourriez-vous donner un exemple? – ShibinRagh

-5

j'ai réussi à le faire fonctionner, ce que je faisais semble correcte:

testImage = new testImage(); 
testImage.src = data:image/png;base64,iVBORw0KG......kSZIkSZIkSZI0u/1/diDteJCiN80AAAAASUVORK5CYII= 

(Au-dessus de l'URL est un exemple)

context.drawImage(testImg,0,0); 

Cela semble fonctionner quand je le lance sur la console Chrome et FireBug

+13

Cela fonctionnera mais c'est crufty et pas la meilleure façon de le faire. –

+0

C'était exactement ce dont j'avais besoin! Merci! –

0

@ robert-hurst a une approche plus propre, mais cette solution peut être utilisée dans des endroits où vous voulez vraiment avoir une copie de Data Url après la copie. Exemples: lorsque vous créez un site Web qui utilise beaucoup d'opérations image/canevas.

// select canvas elements 
    var sourceCanvas = document.getElementsById("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;