Cara Menyalin Isi Satu Kanvas ke Kanvas Lain Secara Lokal

129

Saya ingin menyalin SEMUA konten dari satu kanvas dan mentransfernya ke kanvas lain semua di sisi klien. Saya akan berpikir bahwa saya akan menggunakan metode canvas.toDataURL()dan context.drawImage()untuk mengimplementasikan ini tetapi saya mengalami beberapa masalah.

Solusi saya adalah mendapatkan Canvas.toDataURL()dan menyimpan ini dalam objek Gambar di Javascript, dan kemudian menggunakan context.drawImage()metode untuk menempatkannya kembali.

Namun, saya yakin toDataURLmetode ini mengembalikan tag yang dikodekan 64 bit dengan "data:image/png;base64,"menambahkannya. Ini tampaknya bukan tag yang valid, (saya selalu bisa menggunakan beberapa RegEx untuk menghapus ini), tetapi apakah string yang dikodekan 64 bit SETELAH "data:image/png;base64,"substring gambar yang valid? Bisakah saya mengatakan image.src=iVBORw...ASASDAS, dan menggambar ini kembali di kanvas?

Saya telah melihat beberapa masalah terkait: Menampilkan gambar kanvas dari satu kanvas ke kanvas lain menggunakan base64

Tetapi solusinya tampaknya tidak benar.

J Kao
sumber

Jawaban:

273

Sebenarnya Anda tidak perlu membuat gambar sama sekali. drawImage()akan menerima Canvasserta Imageobjek.

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

Jauh lebih cepat daripada menggunakan ImageDataobjek atau Imageelemen.

Perhatikan bahwa sourceCanvasbisa berupa HTMLImageElement , HTMLVideoElement , atau HTMLCanvasElement . Seperti yang disebutkan oleh Dave dalam komentar di bawah jawaban ini, Anda tidak dapat menggunakan konteks gambar kanvas sebagai sumber Anda . Jika Anda memiliki konteks gambar kanvas dan bukan elemen kanvas tempat pembuatannya, ada referensi ke elemen kanvas asli pada konteks di bawah context.canvas.

Berikut adalah jsPerf untuk mendemonstrasikan mengapa ini adalah satu-satunya cara yang tepat untuk mengkloning kanvas: http://jsperf.com/copying-a-canvas-element

Robert Hurst
sumber
66
sebuah poin kecil yang membuat saya tersandung: meskipun Anda bisa menggambar kanvas ( HTMLCanvasElement), Anda tidak bisa menggambar konteks ( CanvasRenderingContext2D). Gunakan myContext.canvassebagai gantinya.
Dave
3
Komentar @Dave adalah HARUS DIBACA ... woud memberikan +10 jika memungkinkan;). @ Robert-Hurst harus melengkapi jawabannya dengan komentar ini karena dia tidak menyebutkan dari mana source canvasasalnya ...
Paulo Bueno
Bisakah Anda memberikan contoh?
ShibinRagh
@RogerGajraj Sebenarnya kanvas tidak harus terlihat. Ini ditunjukkan di sana => jsfiddle.net/d36wwtvj
Robert Hurst
2

@ robert-hurst memiliki pendekatan yang lebih bersih.

Namun, solusi ini juga dapat digunakan, di tempat-tempat ketika Anda benar-benar ingin memiliki salinan Url Data setelah menyalin. Misalnya, saat Anda membangun situs web yang menggunakan banyak operasi gambar / kanvas.

    // 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
sumber