[JS]<canvas> Download & print image
Objectif
Pouvoir enregistrer et imprimer une image issue d'un élément <canvas>
.
Comme image nous allons nous servir d'un graphique réalisé avec la bibliothèque Chart.js qui est une bibliothèque simple et légère qui permet de réaliser des graphiques et utilisant justement un élément <canvas>
pour le rendu.
Graphique
➜ Cliquez sur les icônes du graphe pour lancer les actions.
Affichage de l'image
On utilise la méthode toDataURL()
de l'élément <canvas>
pour récupérer les données image liées à celui-ci puis on les affecte à l'attribut src
d'un élément <img>
présent dans la page ou crée dynamiquement.
Dans l'exemple ci-dessous l'élément existe déjà dans la page.
function showImage(idCanvas, idImage) {
// récup. de l'élément <img> servant pour l'affichage
const oImg = document.getElementById(idImage);
// récup. de l'élément <canvas>
const canvas = document.getElementById(idCanvas);
// récup. des données de l'image du <canvas>
const dataImage = canvas.toDataURL("image/png");
// affectation des données à l'attribut src de l'élément <img>
oImg.src = dataImage;
}
Impression de l'image
On va récupérer les données image du <canvas>
, comme vu précédemment, ouvrir une nouvelle fenêtre, écrire dans le document pour insérer un élément <img>
en affectant à son attribut src
les données image et enfin lancer l'impression du document en fermant celui-ci l'impression terminée.
function printImage(idCanvas) {
// récup. de l'élément <canvas>
const canvas = document.getElementById(idCanvas);
// récup. des données de l'image du <canvas>
const dataImage = canvas.toDataURL("image/png");
// ouverture d'une nouvelle fenêtre
const fen = window.open();
// ouverture du document pour écriture
fen.document.open();
// insére un élément "<img> avec l'attribut src contenant les données de l'image
fen.document.write("<img src='" + dataImage + "'>");
// fermeture du document
fen.document.close();
// lance l'impression dès que chargé
fen.onload = setTimeout(function() {
fen.print();
fen.close();
}, 100);
}
Enregistrement de l'image
Pour l'enregistrement nous allons passer par un élément <a>
ayant un attribut download
.
Cette méthode ne fonctionne malheureusement pas sous IE-Edge, ceci est lié à la longueur maximum autorisée pour une URL, mais il existe une méthode de remplacement bien plus simple à mettre en place d'ailleurs (voir le code ci-dessous).
Il est également nécessaire de modifier le type des données, en « image/octet-stream », avant affectation à l'attribut href
de l'élément.
function saveImage(idCanvas, nomFichier) {
// nom du fichier pour l'enregistrement
const nomFile = nomFichier || "image.png";
// récup. de l'élément <canvas>
const canvas = document.getElementById(idCanvas);
let dataImage;
// pour IE et Edge c'est simple !!!
// https://technet.microsoft.com/en-us/windows/hh771732(v=vs.60)
if (canvas.msToBlob) {
// crée un objet blob contenant le dessin du canvas
dataImage = canvas.msToBlob();
// affiche l'invite d'enregistrement
window.navigator.msSaveBlob(dataImage, nomFile);
}
else {
// création d'un lien HTML5 download
const lien = document.createElement("A");
// récup. des data de l'image
dataImage = canvas.toDataURL("image/png");
// affectation d'un nom à l'image
lien.download = nomFile;
// modifie le type de données
dataImage = dataImage.replace("image/png", "image/octet-stream");
// affectation de l'adresse
lien.href = dataImage;
// ajout de l'élément
document.body.appendChild(lien);
// simulation du click
lien.click();
// suppression de l'élément devenu inutile
document.body.removeChild(lien);
}
}
Conclusion
Outre le fait que les fonctions ci-dessus pourraient être écrites de façon à les rendre plus génériques et stables,
les bases sont posées pour gérer les données image d'un élément <canvas>
et ce indépendamment de l'exemple pris ici.
Ressources
- HTMLCanvasElement.toDataURL()
- Canvas.msToBlob() méthode pour IE-Edge
- navigator.msSaveBlob(blob, defaultName) méthode pour IE-Edge
- Chart.js documentation