Ist es möglich, das, was auf einer HTML-Leinwand angezeigt wird, als Bild oder PDF zu erfassen oder zu drucken?
Ich möchte ein Bild über Leinwand erzeugen und aus diesem Bild ein PNG generieren können.
Ist es möglich, das, was auf einer HTML-Leinwand angezeigt wird, als Bild oder PDF zu erfassen oder zu drucken?
Ich möchte ein Bild über Leinwand erzeugen und aus diesem Bild ein PNG generieren können.
Antworten:
Hoppla. Die ursprüngliche Antwort war spezifisch für eine ähnliche Frage. Dies wurde überarbeitet:
var canvas = document.getElementById("mycanvas");
var img = canvas.toDataURL("image/png");
Mit dem Wert in IMG können Sie es wie folgt als neues Bild ausschreiben:
document.write('<img src="'+img+'"/>');
var img = new Image(); img.src = canvas.toDataURL(); document.body.appendChild(img);
. Der document.write
Code erstellt die Daten-URL, erstellt eine HTML-Zeichenfolge und fügt dann eine Kopie dieser Zeichenfolge in das DOM ein. Der Browser muss dann diese HTML-Zeichenfolge analysieren, eine weitere Kopie in das Bildelement einfügen und sie dann erneut analysieren, um die zu ändern Daten-URL in Bilddaten, dann kann es endlich das Bild anzeigen. Für ein Bild in Bildschirmgröße ist das eine große Menge an Speicher / Kopieren / Parsen. Nur ein Vorschlag
HTML5 bietet Canvas.toDataURL (Mimetyp), das in der Beta von Opera, Firefox und Safari 4 implementiert ist. Es gibt jedoch eine Reihe von Sicherheitsbeschränkungen (hauptsächlich im Zusammenhang mit dem Zeichnen von Inhalten eines anderen Ursprungs auf die Leinwand).
Sie benötigen also keine zusätzliche Bibliothek.
z.B
<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>
Theoretisch sollte dies ein Bild mit einem grünen Quadrat in der Mitte erstellen und dann zu diesem navigieren, aber ich habe es nicht getestet.
javascript:void(window.open().location = document.getElementsByTagName("canvas")[0].toDataURL("image/png"))
Ich dachte, ich würde den Umfang dieser Frage ein wenig erweitern, mit einigen nützlichen Details zu diesem Thema.
Um die Leinwand als Bild zu erhalten, sollten Sie Folgendes tun:
var canvas = document.getElementById("mycanvas");
var image = canvas.toDataURL("image/png");
Sie können dies verwenden, um das Bild auf die Seite zu schreiben:
document.write('<img src="'+image+'"/>');
Wobei "image / png" ein MIME-Typ ist (PNG ist der einzige, der unterstützt werden muss). Wenn Sie ein Array der unterstützten Typen möchten, können Sie Folgendes tun:
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];
}
}
Sie müssen dies nur einmal pro Seite ausführen - es sollte sich niemals während des Lebenszyklus einer Seite ändern.
Wenn Sie möchten, dass der Benutzer die Datei beim Speichern herunterlädt, können Sie Folgendes tun:
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;
Wenn Sie dies mit verschiedenen MIME-Typen verwenden, müssen Sie beide Instanzen von image / png ändern, nicht jedoch den image / octet-Stream. Erwähnenswert ist auch, dass bei der Verwendung der toDataUrl-Methode ein Sicherheitsfehler auftritt, wenn Sie beim Rendern Ihrer Zeichenfläche domänenübergreifende Ressourcen verwenden.
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);
}
Ich würde " wkhtmltopdf " verwenden. Es funktioniert einfach großartig. Es verwendet die Webkit-Engine (in Chrome, Safari usw. verwendet) und ist sehr einfach zu verwenden:
wkhtmltopdf stackoverflow.com/questions/923885/ this_question.pdf
Das ist es!
Hier ist eine Hilfe, wenn Sie den Download über einen Server durchführen (auf diese Weise können Sie Ihre Datei benennen / konvertieren / nachbearbeiten / usw.):
-Postdaten mit toDataURL
-Stellen Sie die Header
$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");
-Bild erstellen
$data = $_POST['data'];
$img = imagecreatefromstring(base64_decode(substr($data,strpos($data,',')+1)));
-Bild als JPEG exportieren
$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();
-oder als transparentes PNG
imagesavealpha($img, true);
imagepng($img);
die($img);
Eine weitere interessante Lösung ist PhantomJS . Es ist ein kopfloses WebKit, das mit JavaScript oder CoffeeScript geschrieben werden kann.
Einer der Anwendungsfälle ist die Bildschirmaufnahme: Sie können programmgesteuert Webinhalte wie SVG und Canvas erfassen und / oder Website-Screenshots mit Miniaturansicht erstellen.
Der beste Einstiegspunkt ist die Bildschirmaufnahme- Wiki-Seite.
Hier ist ein gutes Beispiel für die Polaruhr (von RaphaelJS):
>phantomjs rasterize.js http://raphaeljs.com/polar-clock.html clock.png
Möchten Sie eine Seite als PDF rendern?
> phantomjs rasterize.js 'http://en.wikipedia.org/w/index.php?title=Jakarta&printable=yes' jakarta.pdf
Wenn Sie jQuery verwenden, was ziemlich viele Leute tun, würden Sie die akzeptierte Antwort folgendermaßen implementieren:
var canvas = $("#mycanvas")[0];
var img = canvas.toDataURL("image/png");
$("#elememt-to-write-to").html('<img src="'+img+'"/>');
.toDataURL
ist native JS.
$('<img>').attr('src',$('#mycanvas')[0].toDataURL('image/png')).appendTo($('#element-to-write-to').empty());
Genau eine Zeile.
Sie können jspdf verwenden, um eine Leinwand in ein Bild oder PDF wie folgt aufzunehmen:
var imgData = canvas.toDataURL('image/png');
var doc = new jsPDF('p', 'mm');
doc.addImage(imgData, 'PNG', 10, 10);
doc.save('sample-file.pdf');
Weitere Informationen: https://github.com/MrRio/jsPDF
Dies ist der andere Weg, ohne Zeichenfolgen, obwohl ich nicht wirklich weiß, ob es schneller ist oder nicht. Anstelle von toDataURL (wie alle Fragen hier vorschlagen). In meinem Fall möchte ich dataUrl / base64 verhindern, da ich einen Array-Puffer oder eine Ansicht benötige. Die andere Methode in HTMLCanvasElement ist also toBlob
. (TypeScript-Funktion):
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));
}
Ein weiterer Vorteil von Blobs besteht darin, dass Sie ObjectUrls erstellen können, um Daten als Dateien darzustellen, ähnlich wie bei HTMLInputFiles 'files'-Mitglied. Mehr Info:
https://developer.mozilla.org/es/docs/Web/API/HTMLCanvasElement/toBlob