html2canvas – Screenshots von Webseiten mit Javascript erstellen

Auf einigen Webseiten wird dem Nutzer die Möglichkeit geboten, Feedback zu geben. Bei Youtube läuft das bspw. so, dass man als „feedbackwilliger“ Nutzer einen Bereich der Webseite markiert und diesen dann kommentieren kann. Nachzuvollziehen ist das über den versteckt im Footer der Seite platzierten Link „Programmfehler melden“.

Youtube-Feedback

Youtube-Feedback

Durch das Projekt html2canvas lässt sich nun sowas ganz ohne Flash lösen: Es wird in einem Canvas das DOM der Seite rekonstruiert und dann mittels der Funktion canvas.toDataURL() ein Datenstream erstellt, der sich dann mit Hilfe eines serverseitigen Scripts in ein vollwertiges Bild umwandeln lässt. Aber der Reihe nach.

Das Setup

<!doctype html> <head> 	<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.8.1/jquery.min.js"></script> 	<script src="https://raw.github.com/niklasvh/html2canvas/master/src/plugins/jquery.plugin.html2canvas.js"></script> 	<script src="http://html2canvas.hertzen.com/js/html2canvas.js?rev034"></script> 	<script src="makeScreenshot.js"></script> </head> <body> 	<div style="width:500px;height:300px;background:red;border:5px solid yellow"> 		<h1 style="color:green">Das ist ein Test</h1> 	</div> </body> </html> 

Logischerweise brauchen wir jQuery, ein Plugin für html2canvas von der Github-Seite des Projekts und die eigentliche Library. Der Body ist unser Testcontent, den wir screenshotten wollen. Inhalt des Scripts makeScreenshot.js:

function postCanvasToURL(data)  { 	data = data.replace('data:image/png;base64,', ''); 	var xhr = new XMLHttpRequest(); 	xhr.open('POST', "post.php", true); 	var boundary = 'this-is-a-string'; 	xhr.setRequestHeader('Content-Type', 'multipart/form-data; boundary=' + boundary); 	request_str = '--' + boundary + '\r\n' + 'Content-Disposition: form-data; name="formelement"; filename="image.png"' + '\r\n' + 				   'Content-Type: image/png' + '\r\n\r\n' + atob(data) + '\r\n' + '--' + boundary + '--';  	var bytes = [];  	for (var i in request_str) 	{ 		bytes.push(request_str[i].charCodeAt(0) & 0xff); 	}  	xhr.send(new Uint8Array(bytes).buffer); }  $(window).ready(function() { 	var options = {onrendered : function(canvas) { postCanvasToURL(canvas.toDataURL()); }}; 	var canvasRecord = $('body').html2canvas(options); }); 

Basierend auf einigen halbgaren Stackoverflow-Antworten (hier, hier und hier) erstellt die Funktion postCanvasToUrl die Data-URL des Canvas im korrekten multipart/form-data-Format als Boundary an das PHP-Script post.php. Mehr passiert nicht. Auf der Serverseite liegt dann die Datei post.php, die den XHR-Request entgegennimmt und beschämend einfach aufgebaut ist:

<?php move_uploaded_file($_FILES['formelement']['tmp_name'], $_FILES['formelement']['name']); 

Wir verschieben einfach nur die Datei, die uns postCanvasToURL im $_FILES – Array serviert – wie bei einem normalen File-Upload eben. Resultat ist das optisch über jeden Zweifel erhabene Bild:

html2canvas-Output

html2canvas-Output

Super Projekt auf jeden Fall! Zu beachten gilt, dass der Browser natürlich Canvas können sollte und der „Screenshot“ in einigen Fällen nicht ganz akkurat ist. Auf der Testkonsole lässt sich hervorragend herumexperimentieren.


Deprecated: Directive 'allow_url_include' is deprecated in Unknown on line 0