Как скопировать содержимое одного холста на другой холст на локальном уровне
Я бы хотел скопировать ВСЕ содержимое одного холста и перенести их на другое на клиентской стороне. Я бы подумал, что я бы использовал методы 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
Но решения не кажутся правильными.
Ответы
Ответ 1
На самом деле вам не нужно создавать изображение вообще. 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. Как указано в Dave в комментарии ниже этого ответа, вы не можете использовать контекст рисования в качестве источника. Если у вас есть контекст рисования холста, а не элемент холста, из которого он был создан, есть ссылка на исходный элемент холста в контексте под context.canvas
.
Вот jsPerf, чтобы показать, почему это единственный правильный способ клонирования холста: http://jsperf.com/copying-a-canvas-element
Ответ 2
@robert-hurst имеет более чистый подход, но это решение может использоваться в тех местах, где вы действительно хотите иметь копию URL-адреса данных после копирования. Примеры: когда вы создаете веб-сайт, на котором много операций с изображением/холстом.
// select canvas elements
var sourceCanvas = document.getElementsById("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;
Ответ 3
Мне удалось заставить его работать, что я сделал правильно:
testImage = new testImage();
testImage.src = data:image/png;base64,iVBORw0KG......kSZIkSZIkSZI0u/1/diDteJCiN80AAAAASUVORK5CYII=
(Пример выше URL-адреса)
context.drawImage(testImg,0,0);
Это работает, когда я запускаю его на консоли в Chrome и FireBug