Чи можливо захопити чи роздрукувати те, що відображається на HTML-полотні у вигляді зображення чи PDF?
Я хотів би генерувати зображення за допомогою полотна та мати змогу генерувати PNG з цього зображення.
Чи можливо захопити чи роздрукувати те, що відображається на HTML-полотні у вигляді зображення чи PDF?
Я хотів би генерувати зображення за допомогою полотна та мати змогу генерувати PNG з цього зображення.
Відповіді:
На жаль Оригінальна відповідь була специфічною для аналогічного питання. Це було переглянуто:
var canvas = document.getElementById("mycanvas");
var img = canvas.toDataURL("image/png");
зі значенням у IMG ви можете записати його як нове зображення так:
document.write('<img src="'+img+'"/>');
var img = new Image(); img.src = canvas.toDataURL(); document.body.appendChild(img);
. document.write
Код робить URL даних, їх робить HTML рядок, потім покласти копію цього рядка в DOM, браузер , тобто розібрати , що HTML - рядок, поставити ще одну копію на елемент зображення, а потім розібрати його знову , щоб включити URL-адреса даних у графічні дані, тоді, нарешті, вона може показати зображення. Для зображення розміру екрану це величезна кількість пам'яті / копіювання / розбору. Просто пропозиція
HTML5 забезпечує Canvas.toDataURL (міметик), який реалізований в Opera, Firefox та Safari 4 beta. Однак існує ряд обмежень щодо безпеки (в основному це стосується малювання вмісту іншого полотна на полотні).
Тому вам не потрібна додаткова бібліотека.
напр
<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>
Теоретично це має створити, а потім перейти до зображення із зеленим квадратом посередині, але я не перевіряв.
javascript:void(window.open().location = document.getElementsByTagName("canvas")[0].toDataURL("image/png"))
Я думав, що трохи розширю сферу цього питання з корисними підказками з цього питання.
Для того щоб отримати полотно як зображення, слід зробити наступне:
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, але не image / octet-stream. Варто також зазначити, що якщо ви використовуєте будь-які міждоменні ресурси при візуалізації свого полотна, під час спроби використання методу toDataUrl у вас виникне помилка безпеки.
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);
}
Я б використовував " wkhtmltopdf ". Це просто чудово працює. Він використовує двигун webkit (використовується в Chrome, Safari тощо), і це дуже просто:
wkhtmltopdf stackoverflow.com/questions/923885/ this_question.pdf
Це воно!
Ось деяка допомога, якщо ви робите завантаження через сервер (таким чином ви можете назвати / конвертувати / переробляти / тощо ваш файл):
-Введення даних за допомогою 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");
-створити зображення
$data = $_POST['data'];
$img = imagecreatefromstring(base64_decode(substr($data,strpos($data,',')+1)));
-експорт зображення у форматі 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();
або як прозорий PNG
imagesavealpha($img, true);
imagepng($img);
die($img);
Ще одне цікаве рішення - 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
Якщо ви використовуєте jQuery, що робить досить багато людей, ви реалізуєте прийняту відповідь так:
var canvas = $("#mycanvas")[0];
var img = canvas.toDataURL("image/png");
$("#elememt-to-write-to").html('<img src="'+img+'"/>');
.toDataURL
є рідним JS.
$('<img>').attr('src',$('#mycanvas')[0].toDataURL('image/png')).appendTo($('#element-to-write-to').empty());
Рівно один рядок.
Ви можете використовувати jspdf для зйомки полотна в зображення або pdf таким чином:
var imgData = canvas.toDataURL('image/png');
var doc = new jsPDF('p', 'mm');
doc.addImage(imgData, 'PNG', 10, 10);
doc.save('sample-file.pdf');
Більше інформації: https://github.com/MrRio/jsPDF
Це інший спосіб, без рядків, хоча я насправді не знаю, швидше це чи ні. Замість toDataURL (як пропонують усі питання тут). У моєму випадку хочу запобігти dataUrl / base64, оскільки мені потрібен буфер масиву або перегляд. Отже, інший метод у HTMLCanvasElement є toBlob
. (Функція TypeScript):
export function canvasToArrayBuffer(canvas: HTMLCanvasElement, mime: string): Promise<ArrayBuffer> {
return new Promise((resolve, reject) => canvas.toBlob(async (d) => {
if (d) {
const r = new FileReader();
r.addEventListener('loadend', e => {
const ab = r.result;
if (ab) {
resolve(ab as ArrayBuffer);
}
else {
reject(new Error('Expected FileReader result'));
}
}); r.addEventListener('error', e => {
reject(e)
});
r.readAsArrayBuffer(d);
}
else {
reject(new Error('Expected toBlob() to be defined'));
}
}, mime));
}
Ще однією перевагою крапів є те, що ви можете створити ObjectUrls для представлення даних у вигляді файлів, подібних до учасників HTMLInputFile. Більше інформації:
https://developer.mozilla.org/es/docs/Web/API/HTMLCanvasElement/toBlob