Захватить холст HTML как gif / jpg / png / pdf?

598

Можно ли захватить или распечатать то, что отображается в холсте html, как изображение или PDF?

Я хотел бы сгенерировать изображение через холст и иметь возможность генерировать png из этого изображения.

Показать ещё 2 комментария
Теги:
export
canvas
png

9 ответов

614
Лучший ответ

К сожалению. Первоначальный ответ был связан с аналогичным вопросом. Это было пересмотрено:

var canvas = document.getElementById("mycanvas");
var img    = canvas.toDataURL("image/png");

со значением в IMG вы можете записать его как новое изображение так:

document.write('<img src="'+img+'"/>');
  • 0
    Спасибо, Майкл, похоже, что getContext вместе с toDataURL сделали бы это
  • 3
    Удивительно! Я использовал это с Processing.js
Показать ещё 22 комментария
95

HTML5 предоставляет Canvas.toDataURL(mimetype), который реализован в бета-версии Opera, Firefox и Safari 4. Однако существует ряд ограничений безопасности (в основном, для рисования содержимого из другого источника на холст).

Поэтому вам не нужна дополнительная библиотека.

например.

 <canvas id=canvas width=200 height=200></canvas>
 <script>
      window.onload = function() {
          var canvas = document.getElementById("canvas");
          var context = canvas.getContext("2d");
          context.fillStyle = "green";
          context.fillRect(50, 50, 100, 100);
          // no argument defaults to image/png; image/jpeg, etc also work on some
          // implementations -- image/png is the only one that must be supported per spec.
          window.location = canvas.toDataURL("image/png");
      }
 </script>

Теоретически это должно создать, а затем перейти к изображению с зеленым квадратом посередине, но я не тестировал.

  • 2
    Где изображение будет сохранено. Расположение в моем местном?
  • 0
    это работает в IE9 тоже?
Показать ещё 4 комментария
31

Я думал, что немного расширить сферу этого вопроса, с некоторыми полезными лакомыми кусочками в этом вопросе.

Чтобы получить холст в качестве изображения, вы должны сделать следующее:

var canvas = document.getElementById("mycanvas");
var image = canvas.toDataURL("image/png");

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

document.write('<img src="'+image+'"/>');

Где "image/png" - это тип mime (png - единственный, который должен поддерживаться). Если вам нужен массив поддерживаемых типов, вы можете сделать что-то в этом роде:

var imageMimes = ['image/png', 'image/bmp', 'image/gif', 'image/jpeg', 'image/tiff']; //Extend as necessary 
var acceptedMimes = new Array();
for(i = 0; i < imageMimes.length; i++) {
    if(canvas.toDataURL(imageMimes[i]).search(imageMimes[i])>=0) {
        acceptedMimes[acceptedMimes.length] = imageMimes[i];
    }
}

Вам нужно всего лишь запустить этот раз на странице - он никогда не должен меняться через жизненный цикл страницы.

Если вы хотите, чтобы пользователь загрузил файл по мере его сохранения, вы можете сделать следующее:

var canvas = document.getElementById("mycanvas");
var image = canvas.toDataURL("image/png").replace("image/png", "image/octet-stream"); //Convert image to 'octet-stream' (Just a download, really)
window.location.href = image;

Если вы используете это с разными типами mime, обязательно измените оба экземпляра image/png, но не изображение/октет-поток. Также стоит упомянуть, что если вы используете какие-либо междоменные ресурсы при рендеринге вашего холста, вы столкнетесь с ошибкой безопасности при попытке использовать метод toDataUrl.

  • 1
    С вашим решением для загрузки файла, я должен выбрать программное обеспечение, которое я хочу использовать, это немного неудобно ... Есть ли способ заменить mime на png после загрузки?
  • 1
    @ So4ne Я так не думаю, это должен быть поток изображений / октетов, чтобы предложить пользователю загрузить файл. Если вы избавитесь от этой строки, вы получите страницу, перенаправляющую на изображение. Я хотел бы знать, если кто-то еще знает способ сделать это красиво, хотя.
Показать ещё 5 комментариев
21

Я бы использовал " wkhtmltopdf". Это просто отлично работает. Он использует движок webkit (используется в Chrome, Safari и т.д.), И он очень прост в использовании:

wkhtmltopdf stackoverflow.com/questions/923885/ this_question.pdf

Что это!

Попробуйте

  • 1
    Я тоже в лагере wkhtmltopdf. Мы использовали его для архивирования и его УДИВИТЕЛЬНОГО.
  • 0
    Как использовать WKHTMLtoPDF на странице, требующей информацию для входа? Я использую Jsreport для преобразования в PDF, но я захватываю свой контент с помощью HTML2Canvas, у меня проблема с отправкой Canvas в качестве параметра в JSreport
Показать ещё 1 комментарий
19
function exportCanvasAsPNG(id, fileName) {

    var canvasElement = document.getElementById(id);

    var MIME_TYPE = "image/png";

    var imgURL = canvasElement.toDataURL(MIME_TYPE);

    var dlLink = document.createElement('a');
    dlLink.download = fileName;
    dlLink.href = imgURL;
    dlLink.dataset.downloadurl = [MIME_TYPE, dlLink.download, dlLink.href].join(':');

    document.body.appendChild(dlLink);
    dlLink.click();
    document.body.removeChild(dlLink);
}
  • 0
    Сохраненный файл остается в формате .svg. Как сохранить его как PNG?
  • 0
    Это хорошее решение за исключением того, что оно может не работать в IE. Получение ошибки «Область данных, переданная системному вызову, слишком мала»
Показать ещё 1 комментарий
12

Вот некоторая помощь, если вы выполняете загрузку через сервер (таким образом вы можете назвать/преобразовать/выполнить постпроцесс /etc ваш файл):

-Почтовые данные с помощью toDataURL

-Установить заголовки

$filename = "test.jpg"; //or png
header('Content-Description: File Transfer');
if($msie = !strstr($_SERVER["HTTP_USER_AGENT"],"MSIE")==false)      
  header("Content-type: application/force-download");else       
  header("Content-type: application/octet-stream"); 
header("Content-Disposition: attachment; filename=\"$filename\"");   
header("Content-Transfer-Encoding: binary"); 
header("Expires: 0"); header("Cache-Control: must-revalidate"); 
header("Pragma: public");

-create image

$data = $_POST['data'];
$img = imagecreatefromstring(base64_decode(substr($data,strpos($data,',')+1)));

-export image как JPEG

$width = imagesx($img);
$height = imagesy($img);
$output = imagecreatetruecolor($width, $height);
$white = imagecolorallocate($output,  255, 255, 255);
imagefilledrectangle($output, 0, 0, $width, $height, $white);
imagecopy($output, $img, 0, 0, 0, 0, $width, $height);
imagejpeg($output);
exit();

-or как прозрачный PNG

imagesavealpha($img, true);
imagepng($img);
die($img);
6

Другим интересным решением является PhantomJS. Это безголовый WebKit, скриптовый с JavaScript или CoffeeScript.

Одним из вариантов использования является захват экрана: вы можете программно захватывать веб-содержимое, в том числе SVG и Canvas, и/или создавать скриншоты веб-сайтов с предварительным просмотром миниатюр.

Лучшая точка входа - это страница экранная заставка.

Вот хороший пример для полярных часов (от RaphaelJS):

>phantomjs rasterize.js http://raphaeljs.com/polar-clock.html clock.png

Вы хотите сделать страницу в PDF?

> phantomjs rasterize.js 'http://en.wikipedia.org/w/index.php?title=Jakarta&printable=yes' jakarta.pdf
  • 1
    +1: PhantomJS - простая, хорошо документированная и продуманная система, идеально подходящая для этой работы. Это позволяет гораздо больше, чем просто захват холста - например, вы можете изменить страницу или ее часть (с помощью JS) перед захватом, чтобы она выглядела именно так, как вы этого хотите. Отлично!
  • 0
    PhantomJs теперь устарел
2

Если вы используете jQuery, который довольно много людей, то вы бы выполнили принятый ответ так:

var canvas = $("#mycanvas")[0];
var img = canvas.toDataURL("image/png");

$("#elememt-to-write-to").html('<img src="'+img+'"/>');
  • 12
    Обратите внимание, что единственное использование jQuery здесь - выбор холста. .toDataURL является родным JS.
  • 0
    У меня есть проблема сохранения. Кто-то может помочь мне увидеть эту ссылку: stackoverflow.com/questions/25131763/…
Показать ещё 1 комментарий
-2

В некоторых версиях Chrome вы можете:

  • Используйте функцию рисования изображения ctx.drawImage(image1, 0, 0, w, h);
  • Щелкните правой кнопкой мыши на холсте

Ещё вопросы

Сообщество Overcoder
Наверх
Меню