Czy można uchwycić lub wydrukować to, co jest wyświetlane na kanwie HTML jako obraz lub pdf?
Chciałbym wygenerować obraz przez płótno i móc wygenerować png z tego obrazu.
Czy można uchwycić lub wydrukować to, co jest wyświetlane na kanwie HTML jako obraz lub pdf?
Chciałbym wygenerować obraz przez płótno i móc wygenerować png z tego obrazu.
Odpowiedzi:
Ups Oryginalna odpowiedź była specyficzna na podobne pytanie. Zostało to poprawione:
var canvas = document.getElementById("mycanvas");
var img = canvas.toDataURL("image/png");
z wartością w IMG możesz zapisać go jako nowy Obraz w następujący sposób:
document.write('<img src="'+img+'"/>');
var img = new Image(); img.src = canvas.toDataURL(); document.body.appendChild(img);
. document.write
Kod czyni URL danych, ich tworzenia ciąg HTML, a następnie oddanie kopię tego napisu w DOM, przeglądarka musi następnie przeanalizować ten ciąg HTML umieścić inną kopię na elemencie obrazu, a następnie analizować je ponownie, aby włączyć adres URL danych do danych obrazu, a następnie w końcu może wyświetlić obraz. Dla obrazu o rozmiarze ekranu, który jest ogromną ilością pamięci / kopiowania / parsowania. Tylko sugestia
HTML5 zapewnia Canvas.toDataURL (mimetype), który jest zaimplementowany w Operze, Firefoksie i Safari 4 beta. Istnieje jednak szereg ograniczeń bezpieczeństwa (głównie związanych z rysowaniem treści z innego źródła na płótnie).
Więc nie potrzebujesz dodatkowej biblioteki.
na przykład
<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>
Teoretycznie powinno to utworzyć, a następnie przejść do obrazu z zielonym kwadratem pośrodku, ale nie testowałem.
javascript:void(window.open().location = document.getElementsByTagName("canvas")[0].toDataURL("image/png"))
Pomyślałem, że nieco rozszerzę zakres tego pytania, z kilkoma przydatnymi ciekawostkami na ten temat.
Aby uzyskać płótno jako obraz, wykonaj następujące czynności:
var canvas = document.getElementById("mycanvas");
var image = canvas.toDataURL("image/png");
Możesz użyć tego do zapisania obrazu na stronie:
document.write('<img src="'+image+'"/>');
Gdzie „image / png” to typ MIME (png jest jedynym, który musi być obsługiwany). Jeśli chcesz mieć tablicę obsługiwanych typów, możesz zrobić coś w ten sposób:
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];
}
}
Musisz uruchomić to tylko raz na stronie - nigdy nie powinno się zmieniać w całym cyklu życia strony.
Jeśli chcesz, aby użytkownik pobierał plik w miarę zapisywania, możesz wykonać następujące czynności:
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;
Jeśli używasz go z różnymi typami mimów, pamiętaj o zmianie obu instancji image / png, ale nie image / stream oktetów. Warto również wspomnieć, że podczas korzystania z zasobów międzydomenowych przy renderowaniu obszaru roboczego podczas próby użycia metody toDataUrl napotkasz błąd bezpieczeństwa.
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);
}
Chciałbym użyć „ wkhtmltopdf ”. Po prostu działa świetnie. Wykorzystuje silnik webkit (używany w Chrome, Safari itp.) I jest bardzo łatwy w użyciu:
wkhtmltopdf stackoverflow.com/questions/923885/ this_question.pdf
Otóż to!
Oto pomoc, jeśli wykonujesz pobieranie przez serwer (w ten sposób możesz nazwać / przekonwertować / postproces / etc plik):
-Post danych za pomocą toDataURL
-Ustaw nagłówki
$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");
-Stwórz obraz
$data = $_POST['data'];
$img = imagecreatefromstring(base64_decode(substr($data,strpos($data,',')+1)));
-eksportuj obraz jako 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();
imagesavealpha($img, true);
imagepng($img);
die($img);
Innym ciekawym rozwiązaniem jest PhantomJS . Jest to bezgłowy skrypt WebKit ze skryptami JavaScript lub CoffeeScript.
Jednym z przypadków użycia jest przechwytywanie ekranu: możesz programowo przechwytywać zawartość sieci, w tym SVG i Canvas i / lub tworzyć zrzuty ekranu witryny internetowej z podglądem miniatur.
Najlepszym punktem wejścia jest zrzut ekranu strony wiki.
Oto dobry przykład zegara polarnego (z RaphaelJS):
>phantomjs rasterize.js http://raphaeljs.com/polar-clock.html clock.png
Czy chcesz renderować stronę do pliku PDF?
> phantomjs rasterize.js 'http://en.wikipedia.org/w/index.php?title=Jakarta&printable=yes' jakarta.pdf
Jeśli używasz jQuery, co robi całkiem sporo osób, wówczas zaimplementuj zaakceptowaną odpowiedź w następujący sposób:
var canvas = $("#mycanvas")[0];
var img = canvas.toDataURL("image/png");
$("#elememt-to-write-to").html('<img src="'+img+'"/>');
.toDataURL
jest rodzimym JS.
$('<img>').attr('src',$('#mycanvas')[0].toDataURL('image/png')).appendTo($('#element-to-write-to').empty());
Dokładnie jedna linia.
Możesz użyć jspdf, aby uchwycić płótno na obrazie lub pdf:
var imgData = canvas.toDataURL('image/png');
var doc = new jsPDF('p', 'mm');
doc.addImage(imgData, 'PNG', 10, 10);
doc.save('sample-file.pdf');
Więcej informacji: https://github.com/MrRio/jsPDF
To jest inny sposób, bez ciągów, chociaż tak naprawdę nie wiem, czy jest szybszy, czy nie. Zamiast toDataURL (jak proponują wszystkie pytania tutaj). W moim przypadku chcę zapobiec dataUrl / base64, ponieważ potrzebuję bufora lub widoku tablicy. Tak więc inną metodą w HTMLCanvasElement jest toBlob
. (Funkcja 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));
}
Kolejną zaletą obiektów blob jest to, że można tworzyć ObjectUrls do reprezentowania danych jako pliki, podobnie jak członek „plików” HTMLInputFile. Więcej informacji:
https://developer.mozilla.org/es/docs/Web/API/HTMLCanvasElement/toBlob