Bir Tuvalin İçeriğini Başka Bir Tuvale Yerel Olarak Kopyalama


129

Bir tuvalin TÜM içeriğini kopyalayıp istemci tarafında diğerine aktarmak istiyorum. Bunu uygulamak için canvas.toDataURL()ve context.drawImage()yöntemini kullanacağımı düşünürdüm ama birkaç sorunla karşılaşıyorum.

Benim çözümüm, bunu Canvas.toDataURL()Javascript'teki bir Image nesnesine alıp depolamak ve ardından context.drawImage()geri yerleştirmek için yöntemi kullanmak olacaktır.

Bununla birlikte, toDataURLyöntemin "data:image/png;base64,"başına eklenen 64 bit kodlanmış bir etiket döndürdüğüne inanıyorum . Bu geçerli bir etiket gibi görünmüyor (bunu kaldırmak için her zaman biraz RegEx kullanabilirim), ancak bu 64 bit kodlanmış dize, "data:image/png;base64,"alt dizeden SONRA geçerli bir resim mi? Bunu söyleyebilir miyim image.src=iVBORw...ASASDASve bunu tuvale geri çekebilir miyim ?

Bazı ilgili sorunlara baktım: Base64 kullanarak bir tuvalden başka bir tuvale tuval görüntüsünü görüntüleyin

Ancak çözümler doğru görünmüyor.

Yanıtlar:


273

Aslında bir görüntü oluşturmanıza gerek yok. hem bir nesneyi hem de bir nesneyi drawImage()kabul eder .CanvasImage

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

Bir ImageDatanesneyi veya Imageöğeyi kullanmaktan çok daha hızlı .

Not sourceCanvasbir olabilir HTMLImageElement , HTMLVideoElement veya HTMLCanvasElement . Dave tarafından bu cevabın altındaki bir yorumda belirtildiği gibi, kaynağınız olarak bir tuval çizim bağlamı kullanamazsınız . Oluşturulduğu kanvas öğesi yerine bir kanvas çizim bağlamınız varsa, altındaki bağlamda orijinal kanvas öğesine bir referans vardır.context.canvas .

İşte bir tuvali klonlamanın tek doğru yolunun neden bu olduğunu gösteren bir jsPerf: http://jsperf.com/copying-a-canvas-element


67
Beni takıldı küçük nokta: Eğer bir tuval (çizebilirsiniz iken HTMLCanvasElement), sen olamaz bir bağlam çizin ( CanvasRenderingContext2D). myContext.canvasBunun yerine kullanın .
Dave

3
@Dave yorumu mutlaka OKUNMALIDIR ... woud mümkünse +10 verin;). @ Robert-Hurst, nereden source canvasgeldiğini belirtmediği için cevabını bu yorumla tamamlamalı ...
Paulo Bueno

Lütfen bir örnek verebilir misiniz?
ShibinRagh

@RogerGajraj Aslında tuvalin görünür olması gerekmiyor. Bu orada gösterilmiştir => jsfiddle.net/d36wwtvj
Robert Hurst

2

@ robert-hurst'ın daha temiz bir yaklaşımı var.

Ancak bu çözüm, kopyaladıktan sonra Veri URL'sinin gerçekten bir kopyasını almak istediğiniz yerlerde de kullanılabilir. Örneğin, çok sayıda görüntü / tuval işlemi kullanan bir web sitesi oluştururken.

    // 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;
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.