web-dev-qa-db-fra.com

Capturer HTML Canvas en tant que gif / jpg / png / pdf?

Est-il possible de capturer ou d'imprimer ce qui est affiché dans une toile html sous forme d'image ou de fichier PDF?

J'aimerais générer une image via canvas et pouvoir générer un png à partir de cette image.

674
Parand

Oops. La réponse originale était spécifique à une question similaire. Cela a été révisé:

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

avec la valeur dans IMG, vous pouvez l'écrire comme une nouvelle image comme ceci:

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

HTML5 fournit Canvas.toDataURL (type MIME) qui est implémenté dans Opera, Firefox et Safari 4 beta. Cependant, il existe un certain nombre de restrictions de sécurité (principalement liées au dessin de contenu sur une autre origine).

Donc, vous n'avez pas besoin d'une bibliothèque supplémentaire.

par exemple.

 <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>

Théoriquement, cela devrait créer puis naviguer vers une image avec un carré vert au milieu, mais je n'ai pas encore testé.

112
olliej

Je pensais élargir un peu le champ de cette question, avec quelques détails utiles à ce sujet.

Pour obtenir le canevas sous forme d'image, procédez comme suit:

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

Vous pouvez l'utiliser pour écrire l'image sur la page:

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

Où "image/png" est un type mime (png est le seul qui doit être pris en charge). Si vous souhaitez un tableau des types pris en charge, vous pouvez faire quelque chose dans le sens de ceci:

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];
    }
}

Il vous suffit de l'exécuter une fois par page - cela ne devrait jamais changer pendant le cycle de vie d'une page.

Si vous souhaitez que l'utilisateur télécharge le fichier tel qu'il est enregistré, vous pouvez procéder comme suit:

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;

Si vous utilisez cela avec différents types MIME, veillez à modifier les deux instances de image/png, mais pas l'image/octet-stream. Il convient également de noter que si vous utilisez des ressources inter-domaines pour rendre votre canevas, vous rencontrerez une erreur de sécurité lorsque vous essayez d'utiliser la méthode toDataUrl.

41
meiamsome
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);
}
32
david.barkhuizen

Je voudrais utiliser " wkhtmltopdf ". Cela fonctionne très bien. Il utilise un moteur Webkit (utilisé dans Chrome, Safari, etc.) et il est très facile à utiliser:

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

C'est ça!

Essayez-le

21
lepe

Voici une aide si vous effectuez le téléchargement via un serveur (vous pouvez ainsi nommer/convertir/post-traiter votre fichier, etc.):

-Publier des données en utilisant toDataURL

-Définissez les en-têtes

$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");

-créer une image

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

-exporter l'image en 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();

-ou en PNG transparent

imagesavealpha($img, true);
imagepng($img);
die($img);
15
user669677

Une autre solution intéressante est PhantomJS . C'est un WebKit sans tête scriptable avec JavaScript ou CoffeeScript.

L'un des cas d'utilisation est la capture d'écran: vous pouvez capturer par programme des contenus Web, y compris des captures d'écran SVG et Canvas et/ou Créer un site Web avec un aperçu miniature.

Le meilleur point d'entrée est la capture d'écran page wiki.

Voici un bon exemple pour l'horloge polaire (de RaphaelJS):

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

Souhaitez-vous rendre une page en PDF?

> phantomjs rasterize.js 'http://en.wikipedia.org/w/index.php?title=Jakarta&printable=yes' jakarta.pdf
9
Cybermaxs

Si vous utilisez jQuery, ce que font beaucoup de gens, implémentez la réponse acceptée comme suit:

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

$("#elememt-to-write-to").html('<img src="'+img+'"/>');
3
Pattle

Vous pouvez utiliser jspdf pour capturer une toile dans une image ou un pdf comme ceci:

var imgData = canvas.toDataURL('image/png');              
var doc = new jsPDF('p', 'mm');
doc.addImage(imgData, 'PNG', 10, 10);
doc.save('sample-file.pdf');

Plus d'infos: https://github.com/MrRio/jsPDF

1
ferralucho