Est-il possible de capturer ou d'imprimer ce qui est affiché dans un canevas html en tant qu'image ou pdf?
J'aimerais générer une image via canvas et pouvoir générer un png à partir de cette image.
Est-il possible de capturer ou d'imprimer ce qui est affiché dans un canevas html en tant qu'image ou pdf?
J'aimerais générer une image via canvas et pouvoir générer un png à partir de cette image.
Réponses:
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+'"/>');
var img = new Image(); img.src = canvas.toDataURL(); document.body.appendChild(img);
. Le document.write
code crée l'URL des données, les crée une chaîne HTML, puis met une copie de cette chaîne dans le DOM, le navigateur doit ensuite analyser cette chaîne HTML, mettre une autre copie sur l'élément image, puis l'analyser à nouveau pour activer URL de données en données d'image, puis enfin il peut afficher l'image. Pour une image de taille d'écran, c'est une énorme quantité de mémoire / copie / analyse. Juste une suggestion
HTML5 fournit Canvas.toDataURL (mimetype) qui est implémenté dans Opera, Firefox et Safari 4 beta. Il existe cependant un certain nombre de restrictions de sécurité (principalement liées au dessin de contenu d'une autre origine sur le canevas).
Vous n'avez donc 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 testé.
javascript:void(window.open().location = document.getElementsByTagName("canvas")[0].toDataURL("image/png"))
J'ai pensé étendre un peu la portée de cette question, avec quelques détails utiles sur la question.
Pour obtenir la toile en tant qu'image, vous devez procéder 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];
}
}
Vous n'avez besoin de l'exécuter qu'une fois par page - cela ne devrait jamais changer tout au long du 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 l'utilisez avec différents types de mime, assurez-vous de modifier les deux instances de image / png, mais pas le flux image / octet. Il convient également de mentionner que si vous utilisez des ressources interdomaines pour le rendu de votre canevas, vous rencontrerez une erreur de sécurité lorsque vous essayez d'utiliser la méthode 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);
}
J'utiliserais " wkhtmltopdf ". Cela fonctionne très bien. Il utilise le 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!
Voici une aide si vous effectuez le téléchargement via un serveur (de cette façon, vous pouvez nommer / convertir / post-traiter / etc votre fichier):
-Publier des données en utilisant toDataURL
-Réglez 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 au format 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);
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 SVG et Canvas et / ou créer des captures d'écran de sites Web avec aperçu des vignettes.
Le meilleur point d'entrée est la page wiki de capture d'écran .
Voici un bon exemple pour l'horloge polaire (de RaphaelJS):
>phantomjs rasterize.js http://raphaeljs.com/polar-clock.html clock.png
Voulez-vous rendre une page au format PDF?
> phantomjs rasterize.js 'http://en.wikipedia.org/w/index.php?title=Jakarta&printable=yes' jakarta.pdf
Si vous utilisez jQuery, ce que font beaucoup de gens, alors vous implémenteriez 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+'"/>');
.toDataURL
est natif JS.
$('<img>').attr('src',$('#mycanvas')[0].toDataURL('image/png')).appendTo($('#element-to-write-to').empty());
Exactement une ligne.
Vous pouvez utiliser jspdf pour capturer un canevas dans une image ou 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'informations: https://github.com/MrRio/jsPDF
C'est l'inverse, sans cordes même si je ne sais pas vraiment si c'est plus rapide ou non. Au lieu de toDataURL (comme toutes les questions proposées ici). Dans mon cas, je veux empêcher dataUrl / base64 car j'ai besoin d'un tampon ou d'une vue de tableau. Donc, l'autre méthode dans HTMLCanvasElement est toBlob
. (Fonction 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));
}
Un autre avantage des blobs est que vous pouvez créer des ObjectUrls pour représenter les données sous forme de fichiers, similaire au membre «files» de HTMLInputFile. Plus d'informations:
https://developer.mozilla.org/es/docs/Web/API/HTMLCanvasElement/toBlob