J'ai récemment utilisé html2canvas.js lors de l'écriture de projets, qui peuvent réaliser la fonction de capture d'écran de la page, mais j'ai rencontré de nombreux pièges, je vais donc écrire un essai pour les enregistrer.
Lorsque vous utilisez html2canvas, vous pouvez rencontrer des problèmes tels que seule l'interface visuelle peut être capturée, la capture d'écran n'a pas de couleur d'arrière-plan et la balise svg ne peut pas être capturée. Ce qui suit est une explication détaillée.
1. Importez html2canvas.jsInutile de dire que cela peut être obtenu sur github : https://github.com/niklasvh/html2canvas
Vous pouvez également importer le lien directement : <script src=https://cdn.bootcss.com/html2canvas/0.5.0-beta4/html2canvas.js></script>
Il est également très simple à utiliser. Vous pouvez trouver l'API spécifique en ligne et utiliser simplement image/png pour générer des images png.
Parmi eux, $(#xxx) est le div que vous souhaitez intercepter. Il peut être obtenu via jquery, bien sûr, il peut également être obtenu via un document.
html2canvas($(#xxx), { onrendu : function (canvas) { var url = canvas.toDataURL(image/png); window.location.href = url; } });
Pour d'autres types d'images tels que jpg, image/jpeg, etc., vous pouvez interroger l'API par vous-même.
En fait, la simple capture d’écran a été complétée ici. Si l’interface est un peu plus compliquée, divers pièges peuvent apparaître. Résolvons-les un par un.
2. Problème : SVG ne peut pas être interceptéLorsque nous interceptons un div, s'il y a une balise svg dans le div, elle ne peut pas être interceptée dans des circonstances normales. Par exemple, si nous interceptons un organigramme, nous obtiendrons quelque chose comme ceci :
On peut voir que les lignes de l'organigramme ne sont pas interceptées, c'est-à-dire que le svg n'est pas intercepté. La solution pour le moment est de convertir le svg en canevas, puis de prendre une capture d'écran et de télécharger directement le code.
Chaque boucle ici consiste à parcourir toutes les balises SVG et à les convertir toutes en toile.
if (typeof html2canvas !== 'undefined') { //Ce qui suit est le traitement de svg var nodesToRecover = []; var nodesToRemove = []; var svgElem = cloneDom.find('svg'); (index, nœud) { var parentNode = node.parentNode; var svg = node.outerHTML.trim(); var toile = document.createElement('canvas'); toile.largeur = 650; toile.hauteur = 798; if (node.style.position) { toile.style.position += noeud.style .position; canvas.style.left += node.style.left; canvas.style.top += node.style.top } nodesToRecover.push({ parent : parentNode, enfant : nœud } ; parentNode.removeChild(node); nodesToRemove.push({ parent : parentNode, enfant : parentNode.appendChild(canvas });
Canvg.js et son fichier de dépendance rgbcolor.js sont nécessaires ici. Ils peuvent être téléchargés directement depuis Internet ou importés directement.
3. Le problème de la transparence de l'arrière-planC'est en fait très simple, car il est transparent par défaut. Il existe un paramètre background dans html2canvas pour ajouter une couleur d'arrière-plan, comme suit :
html2canvas(cloneDom, {onrendered: function(canvas) { var url =canvas.toDataURL(image/png); }, background:#fafafa});4. Le problème de ne pouvoir capturer que la partie visible
Si le div qui doit être intercepté dépasse l'interface, vous pouvez rencontrer le problème d'une interception incomplète. Comme le montre l'image ci-dessus, il n'y a que la moitié du contenu, car la partie invisible est masquée et html2canvas ne peut pas intercepter le contenu. DOM caché.
La solution à ce stade est donc d'utiliser le clonage, de placer une copie de la partie qui doit être interceptée en bas de la page, puis d'utiliser html2canvas pour intercepter le div complet. Une fois l'interception terminée, supprimez cette partie du. contenu. Le code complet est le suivant :
function showQRCode() { scrollTo(0, 0); //Clone du nœud, la valeur par défaut est false, c'est-à-dire que les attributs de la méthode ne sont pas copiés et true correspond à toutes les copies. var cloneDom = $(#d1).clone(true); //Définit l'attribut z-index du nœud cloné, tant qu'il est inférieur au nœud cloné. cloneDom.css({ background-color : #fafafa, position : absolue, top : 0px, z-index : -1, hauteur : 798, largeur : 650 }); /Ce qui suit est le traitement de svg var nodesToRecover = []; var nodesToRemove = []; cloneDom.find('svg');//divReport est l'identifiant du dom qui doit être intercepté dans une image svgElem.each(function (index, node) { var parentNode = node.parentNode; var svg = node.outerHTML .trim(); var toile = document.createElement('toile'); toile.largeur = 650; toile.hauteur = 798; canvg(canvas, svg); if (node.style.position) { canvas.style.position += node.style.position; canvas.style.left += node.style.left; .style.top; } nodesToRecover.push({ parent : parentNode, enfant : nœud }); parentNode.removeChild(node); canvas }); parentNode.appendChild(canvas }); //Ajouter dynamiquement le nœud cloné au corps. $(body).append(cloneDom); html2canvas(cloneDom, { onrendered: function(canvas) { var url =canvas.toDataURL(image/png); window.location.href = url ; cloneDom.remove(); // Effacer le contenu cloné}, arrière-plan :#fafafa });
Ici, clonez d'abord le div à intercepter et définissez le z-index au minimum pour éviter de provoquer une interface inesthétique. Ensuite, le svg est traité, ce qui a été analysé ci-dessus. Enfin, le nœud de clonage est ajouté au corps.
Lors du rendu, nous pouvons directement utiliser location.href pour accéder à l'image, l'enregistrer ou écrire l'URL dans le src de img et l'afficher sur l'interface, comme $('#imgId').attr('src ' ,url);
Enfin, l'image qui vient d'être capturée peut être affichée sur l'interface :
5. Téléchargez l'image et enregistrez-la dans la base de données, puis obtenez l'image à afficher dans l'interface.Maintenant que l'URL est obtenue, elle doit être téléchargée sur le backend, stockée dans la base de données, puis chargée dans une autre interface affichée. Je suis généralement habitué à utiliser l'URL pour stocker les chemins d'image au lieu du stockage blob.
Parce que j'ai besoin de récupérer l'image dans une autre interface, j'ai stocké l'image dans un répertoire de ressources au même niveau que la webapp. Le code est le suivant :
//Stocke l'image et renvoie le chemin de l'image BASE64Decoder decoder = new BASE64Decoder(); byte[] b = decoder.decodeBuffer(product.getProPic().substring(data:image/png;base64,.length())); ByteArrayInputStream bais = new ByteArrayInputStream(b); BufferedImage bi1 = ImageIO.read(bais String); url = user_resource + File.separator + img + File.separator + product_+UUID.randomUUID().toString().replace(-, )+.png; String totalUrl = System.getProperty(root) + url; nouveau fichier (totalUrl); ImageIO.write (bi1, png, w2); //Stocker le chemin relatif de l'image dans la base de données int res = productMapper.insertSelective(product);
Comme une autre logique est impliquée ici, seule une partie du code est incluse.
BASE64Decoder est utilisé ici pour stocker des images. Après avoir obtenu l'image, nous devons utiliser une sous-chaîne pour intercepter le contenu de data:image/png;base64, car ce qui suit est l'URL de l'image, url.substring(data:image/png;base64,.length())
.
Pour le chemin, l'URL dans le code ci-dessus est le contenu que j'ai stocké dans la base de données, et totalUrl est le chemin réel stocké lors de l'opération d'écriture réelle d'ImageIO. Le répertoire racine du projet obtenu par la méthode getProperty() peut être. configuré dans web.xml Le contenu suivant, puis System.getProperty(root) peuvent être utilisés.
<!-- Configurer le système pour obtenir le répertoire racine du projet--><context-param> <param-name>webAppRootKey</param-name> <param-value>root</param-value></context-param ><listener > <listener-class> org.springframework.web.util.WebAppRootListener </listener-class></listener>
Désormais, l'URL de l'image est stockée dans la base de données et l'image elle-même est stockée dans le répertoire du projet sous Tomcat.
Enfin, pour l'obtenir depuis l'interface, ajoutez simplement le nom du projet devant l'url actuelle < img class =depot-img src =<%=request.getContextPath()%>/`+e.proPic+` >
.
Ensuite, vous pouvez voir l'image affichée sur l'interface :
Ce qui précède représente l’intégralité du contenu de cet article. J’espère qu’il sera utile à l’étude de chacun. J’espère également que tout le monde soutiendra le réseau VeVb Wulin.