Ich habe kürzlich beim Schreiben von Projekten html2canvas.js verwendet, mit dem die Screenshot-Funktion der Seite realisiert werden kann, bin jedoch auf viele Fallstricke gestoßen, daher werde ich einen Aufsatz schreiben, um sie aufzuzeichnen.
Bei der Verwendung von html2canvas können Probleme auftreten, z. B. dass nur die visuelle Oberfläche erfasst werden kann, der Screenshot keine Hintergrundfarbe hat und das SVG-Tag nicht erfasst werden kann. Im Folgenden finden Sie eine detaillierte Erklärung.
1. Importieren Sie html2canvas.jsSelbstverständlich kann dies von Github bezogen werden: https://github.com/niklasvh/html2canvas
Sie können den Link auch direkt importieren: <script src=https://cdn.bootcss.com/html2canvas/0.5.0-beta4/html2canvas.js></script>
Es ist auch sehr einfach zu verwenden. Sie können die spezifische API online finden und einfach image/png verwenden, um PNG-Bilder zu generieren.
Darunter ist $(#xxx) das Div, das Sie abfangen möchten. Es kann natürlich auch über document abgerufen werden.
html2canvas($(#xxx), { onrendered: function (canvas) { var url = canvas.toDataURL(image/png); window.location.href = url; } });
Für andere Bildtypen wie JPG, Bild/JPEG usw. können Sie die API selbst abfragen.
Tatsächlich wurde der einfache Screenshot hier fertiggestellt. Wenn die Benutzeroberfläche etwas komplizierter ist, können verschiedene Fallstricke auftreten.
2. Problem, dass SVG nicht abgefangen werden kannWenn wir ein Div abfangen und ein SVG-Tag im Div vorhanden ist, kann es unter normalen Umständen nicht abgefangen werden. Wenn wir beispielsweise ein Flussdiagramm abfangen, erhalten wir so etwas:
Es ist ersichtlich, dass die Linien des Flussdiagramms nicht abgefangen werden, d.
Die Each-Schleife hier besteht darin, alle SVG-Tags zu durchlaufen und sie alle in Canvas zu konvertieren
if (typeof html2canvas !== 'undefiniert') { //Das Folgende ist die Verarbeitung von SVG var nodesToRemove = []; var svgElem = cloneDom.find('svg'); ( index, node) { var parentNode = node.parentNode; var svg = node.outerHTML.trim(); var canvas = document.createElement('canvas'); canvas.width = 650; canvg(canvas, svg); .position; canvas.style.left += node.style.top += node.style.top } nodesToRecover.push({ parent: parentNode, child: node }); parentNode.removeChild(node); nodesToRemove.push({ parent: parentNode, child: canvas });
Hier werden Canvg.js und seine Abhängigkeitsdatei rgbcolor.js benötigt. Diese können direkt aus dem Internet heruntergeladen oder direkt importiert werden.
3. Das Problem der HintergrundtransparenzDies ist eigentlich sehr einfach, da es standardmäßig transparent ist. In html2canvas gibt es einen Parameter Hintergrund, um eine Hintergrundfarbe hinzuzufügen, wie folgt:
html2canvas(cloneDom, { onrendered: function(canvas) { var url =canvas.toDataURL(image/png); }, background:#fafafa});4. Das Problem, nur den sichtbaren Teil erfassen zu können
Wenn das abzufangende Div die Schnittstelle überschreitet, tritt möglicherweise das Problem einer unvollständigen Abfangung auf. Wie im Bild oben gezeigt, ist nur die Hälfte des Inhalts vorhanden. Dies liegt daran, dass der unsichtbare Teil ausgeblendet ist und html2canvas ihn nicht abfangen kann verstecktes DOM.
Daher besteht die Lösung zu diesem Zeitpunkt darin, das Klonen zu verwenden, eine Kopie des Teils, der abgefangen werden muss, am Ende der Seite zu platzieren und dann mit html2canvas das gesamte Div abzufangen. Entfernen Sie nach Abschluss des Abfangens diesen Teil Der vollständige Code lautet wie folgt:
function showQRCode() { scrollTo(0, 0); // Knoten klonen, der Standardwert ist false, das heißt, die Methodenattribute werden nicht kopiert, und true sind alle Kopien. var cloneDom = $(#d1).clone(true); //Legen Sie das Z-Index-Attribut des geklonten Knotens fest, solange es niedriger ist als der des geklonten Knotens. cloneDom.css({ Hintergrundfarbe: #fafafa, Position: absolut, oben: 0px, Z-Index: -1, Höhe: 798, Breite: 650 }); if (typeof html2canvas !== 'undefiniert') { / /Das Folgende ist die Verarbeitung von svg var nodesToRecover = []; var nodesToRemove = []; cloneDom.find('svg');//divReport ist die ID des Doms, der in ein Bild abgefangen werden muss svgElem.each(function (index, node) { var parentNode = node.parentNode; var svg = node.outerHTML .trim(); var canvas = document.createElement('canvas'); 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, child: node }); canvas }); parentNode.appendChild(canvas }); //Den geklonten Knoten dynamisch anhängen. $(body).append(cloneDom); html2canvas(cloneDom, { onrendered: function(canvas) { var url =canvas.toDataURL(image/png); window.location.href = url ; cloneDom.remove(); // Geklonten Inhalt löschen}, Hintergrund:#fafafa });
Klonen Sie hier zunächst das abzufangende Div und setzen Sie den Z-Index auf das Minimum, um eine unansehnliche Schnittstelle zu vermeiden. Anschließend wird der oben analysierte SVG-Knoten angehängt.
In onrendered können wir location.href direkt verwenden, um zu springen, um das Bild anzuzeigen, es zu speichern oder die URL in den src von img zu schreiben und auf der Schnittstelle anzuzeigen, z. B. $('#imgId').attr('src ' ,URL);
Abschließend kann das gerade aufgenommene Bild auf der Oberfläche angezeigt werden:
5. Laden Sie das Bild hoch, speichern Sie es in der Datenbank und rufen Sie das Bild zur Anzeige in der Benutzeroberfläche ab.Nachdem die URL nun erhalten wurde, muss sie in das Backend hochgeladen, in der Datenbank gespeichert und dann in eine andere angezeigte Oberfläche geladen werden. Ich bin es im Allgemeinen gewohnt, URLs zum Speichern von Bildpfaden anstelle von Blob-Speicher zu verwenden.
Da ich das Bild in einer anderen Schnittstelle abrufen muss, habe ich das Bild in einem Ressourcenverzeichnis auf derselben Ebene wie die Webanwendung gespeichert. Der Code lautet wie folgt:
//Speichern Sie das Bild und geben Sie den Bildpfad zurück 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); url = user_resource + File.separator + img + File.separator + product_+UUID.randomUUID().toString().replace(-, )+.png; String totalUrl = System.getProperty(root) + url; File w2 = new File(totalUrl); ImageIO.write(bi1, png, w2); //Speichern Sie den relativen Pfad des Bildes in der Datenbank int res = productMapper.insertSelective(product); //Zur Datenbank hinzufügen
Da hier eine andere Logik beteiligt ist, ist nur ein Teil des Codes enthalten.
BASE64Decoder wird hier zum Speichern von Bildern verwendet. Nachdem wir das Bild erhalten haben, müssen wir einen Teilstring verwenden, um den Inhalt von data:image/png;base64 abzufangen, da das Folgende die URL des Bildes ist: url.substring(data:image/png;base64,.length())
.
Für den Pfad ist die URL im obigen Code der Inhalt, den ich in der Datenbank gespeichert habe, und totalUrl ist der tatsächliche Pfad, der während des tatsächlichen Schreibvorgangs von ImageIO gespeichert wurde. Das Stammverzeichnis des Projekts kann sein In web.xml konfiguriert Der folgende Inhalt und dann System.getProperty(root) können verwendet werden.
<!-- Konfigurieren Sie das System zum Abrufen des Projektstammverzeichnisses--><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>
Jetzt wird die URL des Bildes in der Datenbank gespeichert und das Bild selbst wird im Verzeichnis des Projekts unter Tomcat gespeichert.
Um es schließlich von der Schnittstelle zu erhalten, fügen Sie einfach den Projektnamen vor der aktuellen URL < img class =depot-img src =<%=request.getContextPath()%>/`+e.proPic+` >
hinzu.
Dann können Sie das auf der Benutzeroberfläche angezeigte Bild sehen:
Das Obige ist der gesamte Inhalt dieses Artikels. Ich hoffe, dass er für das Studium aller hilfreich ist. Ich hoffe auch, dass jeder das VeVb Wulin Network unterstützt.