Як скопіювати вміст одного полотна на інше полотно локально


129

Я хотів би скопіювати ВСІ вмісти одного полотна та перенести їх на інше все на стороні клієнта. Я б подумав, що я б скористався методом canvas.toDataURL()і context.drawImage()методом для цього, але я стикаюся з кількома проблемами.

Моїм рішенням було б отримати Canvas.toDataURL()і зберегти це в об’єкт Image в Javascript, а потім скористатися context.drawImage()методом, щоб повернути його назад.

Однак я вважаю, що toDataURLметод повертає 64-бітний кодований тег з попередньою "data:image/png;base64,"для нього. Здається, це не є дійсним тегом (я завжди міг використовувати якийсь RegEx, щоб видалити це), але чи 64-бітовий кодований рядок ПІСЛЯ "data:image/png;base64,"підрядки дійсного зображення? Чи можу я сказати image.src=iVBORw...ASASDASі намалювати це назад на полотні?

Я розглянув деякі пов’язані проблеми: Відображення зображення полотна з одного полотна на інше полотно, використовуючи base64

Але рішення не здаються правильними.

Відповіді:


273

Насправді вам взагалі не потрібно створювати зображення. 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


66
невеличкий пункт, який мене спонукав: хоча ви можете намалювати полотно ( HTMLCanvasElement), ви не можете намалювати контекст ( CanvasRenderingContext2D). Використовуйте myContext.canvasзамість цього.
Дейв

3
@Dave коментар ОБОВ'ЯЗКОВО читати ... Ви б дали +10, якщо можливо;). @ Роберт-Херст повинен доповнити свою відповідь цим коментарем, оскільки він не уточнює, звідки source canvasпоходить ...
Пауло Буено

Чи можете ви надати приклад?
ShibinRagh

@RogerGajraj Насправді полотно не повинно бути видно. Це продемонстровано там => jsfiddle.net/d36wwtvj
Роберт Херст

2

@ Роберт-хурст має більш чистий підхід.

Однак це рішення також може бути використане в місцях, коли ви фактично хочете мати копію 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;
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.