Cách sao chép nội dung của một Canvas sang một Canvas khác cục bộ


128

Tôi muốn sao chép TẤT CẢ nội dung của một khung vẽ và chuyển chúng sang một khung khác ở phía máy khách. Tôi nghĩ rằng tôi sẽ sử dụngcanvas.toDataURL()context.drawImage()phương pháp để thực hiện điều này nhưng tôi đang gặp phải một vài vấn đề.

Giải pháp của tôi là lấy Canvas.toDataURL()và lưu trữ cái này trong một đối tượng Image trong Javascript, và sau đó sử dụngcontext.drawImage() phương thức để đặt nó trở lại.

Tuy nhiên, tôi tin rằng toDataURLphương thức trả về một thẻ được mã hóa 64 bit với tiền tố "data:image/png;base64,"vào nó. Đây dường như không phải là một thẻ hợp lệ, (tôi luôn có thể sử dụng một số RegEx để xóa cái này), nhưng chuỗi mã hóa 64 bit đó SAU "data:image/png;base64,"chuỗi con có phải là hình ảnh hợp lệ không? Tôi có thể nói image.src=iVBORw...ASASDAS, và vẽ lại trên vải không?

Tôi đã xem xét một số vấn đề liên quan: Hiển thị hình ảnh canvas từ khung vẽ này sang khung vẽ khác bằng cách sử dụng base64

Nhưng các giải pháp dường như không chính xác.

Câu trả lời:


273

Thật ra bạn không cần phải tạo một hình ảnh nào cả. drawImage()sẽ chấp nhận một Canvascũng như một Imageđối tượng.

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

Cách nhanh hơn so với sử dụng một ImageDatađối tượng hoặc thành Imagephần.

Lưu ý rằng đó sourceCanvascó thể là HTMLImageE bổ sung , HTMLVideoE bổ sung hoặc HTMLCanvasE bổ sung . Như Dave đã đề cập trong một bình luận bên dưới câu trả lời này, bạn không thể sử dụng bối cảnh vẽ canvas làm nguồn của mình . Nếu bạn có bối cảnh vẽ canvas thay vì thành phần canvas mà nó được tạo từ đó, có một tham chiếu đến thành phần canvas ban đầu trên bối cảnh bên dướicontext.canvas .

Dưới đây là một jsPerf để chứng minh tại sao đây là cách duy nhất đúng để sao chép một khung vẽ: http://jsperf.com/copying-a-canvas-element


66
một điểm nhỏ khiến tôi vấp ngã: trong khi bạn có thể vẽ một khung vẽ ( HTMLCanvasElement), bạn không thể vẽ một bối cảnh ( CanvasRenderingContext2D). Sử dụng myContext.canvasthay thế.
Dave

3
Nhận xét @Dave là PHẢI ĐỌC ... hãy cho +10 nếu có thể;). @ Robert-Hurst phải bổ sung câu trả lời của mình bằng nhận xét này vì anh ta không chỉ định từ đâu source canvasđến ...
Paulo Bueno

Bạn có thể vui lòng cung cấp một ví dụ?
ShibinRagh

@RogerGajraj Trên thực tế, khung vẽ không phải nhìn thấy. Điều này được thể hiện ở đó => jsfiddle.net/d36wwtvj
Robert Hurst

2

@ robert-Hurst có cách tiếp cận sạch hơn.

Tuy nhiên, giải pháp này cũng có thể được sử dụng, ở những nơi bạn thực sự muốn có một bản sao của Url dữ liệu sau khi sao chép. Ví dụ: khi bạn đang xây dựng một trang web sử dụng nhiều thao tác hình ảnh / canvas.

    // 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;
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.