วิธีคัดลอกเนื้อหาของผืนผ้าใบหนึ่งไปยังผืนผ้าใบอื่นในเครื่อง


129

ฉันต้องการคัดลอกเนื้อหาทั้งหมดของผืนผ้าใบหนึ่งผืนและถ่ายโอนไปยังอีกที่หนึ่งทางฝั่งไคลเอ็นต์ ฉันคิดว่าฉันจะใช้canvas.toDataURL()and context.drawImage()method เพื่อนำไปใช้ แต่ฉันพบปัญหาบางประการ

วิธีแก้ปัญหาของฉันคือรับCanvas.toDataURL()และเก็บสิ่งนี้ไว้ในออบเจ็กต์รูปภาพใน Javascript จากนั้นใช้context.drawImage()วิธีการวางกลับ

อย่างไรก็ตามฉันเชื่อว่าtoDataURLเมธอดจะส่งคืนแท็กที่เข้ารหัส 64 บิตพร้อมกับ"data:image/png;base64,"อยู่ข้างหน้า ดูเหมือนว่าจะไม่ใช่แท็กที่ถูกต้อง (ฉันสามารถใช้ RegEx บางตัวเพื่อลบสิ่งนี้ได้เสมอ) แต่สตริงที่เข้ารหัส 64 บิตนั้นหลังจาก"data:image/png;base64,"สตริงย่อยเป็นรูปภาพที่ถูกต้องหรือไม่ ฉันสามารถพูดimage.src=iVBORw...ASASDASและวาดสิ่งนี้กลับมาบนผืนผ้าใบได้ไหม

ฉันได้ดูปัญหาที่เกี่ยวข้องแล้ว: แสดงภาพแคนวาสจากผืนผ้าใบหนึ่งไปยังผืนผ้าใบอื่นโดยใช้ base64

แต่วิธีแก้ปัญหาดูเหมือนจะไม่ถูกต้อง

คำตอบ:


275

จริงๆแล้วไม่ต้องสร้างภาพเลย drawImage()จะยอมรับCanvasเช่นเดียวกับ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);

เร็วกว่าการใช้ImageDataวัตถุหรือImageองค์ประกอบ

โปรดทราบว่าsourceCanvasอาจจะเป็นHTMLImageElement , HTMLVideoElementหรือHTMLCanvasElement ดังที่เดฟกล่าวไว้ในความคิดเห็นด้านล่างคำตอบนี้คุณไม่สามารถใช้บริบทการวาดภาพแคนวาสเป็นแหล่งที่มาของคุณได้ context.canvasหากคุณมีบริบทการวาดภาพบนผืนผ้าใบแทนขององค์ประกอบผ้าใบมันถูกสร้างขึ้นจากมีการอ้างอิงไปยังองค์ประกอบผ้าใบเดิมกับบริบทภายใต้

นี่คือ jsPerf เพื่อแสดงให้เห็นว่าเหตุใดจึงเป็นวิธีเดียวที่ถูกต้องในการโคลนผ้าใบ: http://jsperf.com/copying-a-canvas-element


67
จุดเล็ก ๆ ที่ทำให้ฉันสะดุด: ในขณะที่คุณสามารถวาดผืนผ้าใบ ( HTMLCanvasElement) คุณไม่สามารถวาดบริบท ( CanvasRenderingContext2D) ได้ ใช้myContext.canvasแทน
Dave

3
ความคิดเห็น @ Dave ต้องอ่าน ... woud ให้ +10 ถ้าเป็นไปได้;) @ Robert-Hurst ต้องเติมเต็มคำตอบของเขาด้วยความคิดเห็นนี้เนื่องจากเขาไม่ได้ระบุว่ามาจากไหนsource canvas...
Paulo Bueno

คุณช่วยยกตัวอย่างได้ไหม
ShibinRagh

@RogerGajraj จริงๆแล้วผ้าใบไม่จำเป็นต้องมองเห็นได้ นี่แสดงให้เห็นที่นั่น => jsfiddle.net/d36wwtvj
Robert Hurst

2

@ robert-hurst มีแนวทางที่สะอาดกว่า

อย่างไรก็ตามโซลูชันนี้อาจใช้ในสถานที่ที่คุณต้องการมีสำเนาของ URL ข้อมูลจริงหลังจากการคัดลอก ตัวอย่างเช่นเมื่อคุณสร้างเว็บไซต์ที่ใช้การดำเนินการเกี่ยวกับรูปภาพ / ผืนผ้าใบจำนวนมาก

    // 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;
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.