2015-04-10 3 views
2

Я пытаюсь объединить два холста HTML в один холст, а затем загрузить их в качестве изображения. Мой код, как показано ниже:Объединить несколько холстов и загрузить как изображение

function downloadCanvas() { 
    var bottleCanvas = document.getElementById('bottleCanvas'); 
    var designCanvas = document.getElementById('editorCanvas'); 

    var bottleContext = bottleCanvas.getContext('2d'); 
    bottleContext.drawImage(designCanvas, 69, 50); 

    var dataURL = bottleCanvas.toDataURL("image/png"); 
    var link = document.createElement('a'); 
    link.download = "bottle-design.png"; 
    link.href = bottleCanvas.toDataURL("image/png").replace("image/png", "image/octet-stream"); 
    link.click(); 
} 

Моя проблема здесь, кажется, следующая строка:

bottleContext.drawImage(designCanvas, 69, 50); 

Это, как предполагается рисовать содержимое одного полотна на другое, что он делает, но потом предотвращает запуск и загрузку последней части кода. Когда я удаляю эту конкретную строку, функция загрузки работает нормально, но, к сожалению, загружает только одну из холстов.

Таким образом, мой вопрос: или что я здесь делаю неправильно? или Как мне объединить два холста HTML, а затем загрузить их в качестве изображения.

(На другой ноте, мой выше код для загрузки хорошо работает только в Chrome - в других браузерах я не могу установить имя файла и установить расширение файла.)

ответ

3

Вы, вероятно, встретив ошибка безопасности, вызванная рисованием изображения, источник которого является кросс-доменом на вашем холсте. Рисование междоменного изображения на любом холсте «испортит» это холст и запретит context.toDataURL и поднимет ошибку безопасности, если вы попытаетесь выполнить toDataURL. Эта же «испорченность» произойдет, если вы нарисуете зараженный холст на незагрязненном холсте.

Исправление состоит в том, чтобы убедиться, что все изображения, которые вы рисуете на холсте, происходят в том же домене, что и ваша веб-страница.

Вот пример кода работает должным образом при использовании изображения, которое не вызывает ошибку безопасности междоменное:

var img=new Image(); 
 
img.crossOrigin='anonymous'; 
 
img.onload=start; 
 
img.src="https://dl.dropboxusercontent.com/u/139992952/multple/fish.jpg"; 
 
function start(){ 
 

 
    var bottleCanvas = document.getElementById('bottleCanvas'); 
 
    var designCanvas = document.getElementById('editorCanvas'); 
 
    var ctxb=bottleCanvas.getContext('2d'); 
 
    var ctxd=editorCanvas.getContext('2d'); 
 

 
    ctxb.drawImage(img,0,0); 
 
    ctxd.fillRect(50,50,50,50); 
 

 
    downloadCanvas(); 
 
} 
 

 
function downloadCanvas() { 
 
    var bottleCanvas = document.getElementById('bottleCanvas'); 
 
    var designCanvas = document.getElementById('editorCanvas'); 
 

 
    var bottleContext = bottleCanvas.getContext('2d'); 
 
    bottleContext.drawImage(designCanvas, 69, 50); 
 

 
    var dataURL = bottleCanvas.toDataURL("image/png"); 
 
    var link = document.createElement('a'); 
 
    link.download = "bottle-design.png"; 
 
    link.href = bottleCanvas.toDataURL("image/png").replace("image/png", "image/octet-stream"); 
 
    link.click(); 
 
}
body{ background-color: ivory; } 
 
canvas{border:1px solid red;}
<canvas id="bottleCanvas" width=300 height=300></canvas> 
 
<canvas id="editorCanvas" width=300 height=300></canvas>

Удовлетворяя ограничения безопасности поперечного происхождения

Вы можете разместить свое изображение на сервере, который уже разрешает доступ к его изображениям через кросс-оригинал. Это то, что я делаю в моем примере выше. Dropbox.com позволяет указать, что изображение, которое оно размещает, может быть нарисовано на холст без «tainting» этого холста.

Вы также можете настроить свой ковш S3, чтобы разрешить доступ к изображениям с кросс-началом. Эта ссылка содержит инструкции по настройке заголовков ответов на серверные изображения с кросс-началом: http://docs.aws.amazon.com/AmazonS3/latest/dev/cors.html

Обратите внимание, что, как и в моем примере, если вы используете изображения с перекрестными изображениями, вы также должны установить флаг image.crossOrigin='anonymous', когда вы изначально создать объект изображения в javascript.

+0

Благодарим за это. Но нет ли способа разрешить размещение одного изображения извне? БутылкаCanvas использует изображение, хранящееся локально, тогда как editorCanvas использует изображение, хранящееся в ведре S3, так как оно будет отличаться для каждого пользователя. –

+1

Невозможно обойти защиту от перекрестного происхождения - вы должны соблюдать ее. Если «локально» хранится на вашем локальном жестком диске (в отличие от каталога на обслуживаемом веб-сайте), тогда это изображение «испортит» ваш холст. Изображения S3 ** могут быть выполнены в соответствии с ограничениями на перекрестную защиту **, но они не делают это из коробки. Я добавил к моему ответу, объяснив больше об этом. Удачи с вашим проектом. – markE