Html2canvas: Möglichkeit, die Auflösung des über toDataURL generierten Bildes zu erhöhen

Erstellt am 10. Juli 2013  ·  58Kommentare  ·  Quelle: niklasvh/html2canvas

Dies ist eher eine Funktionsanfrage. Ich kann das PNG leicht generieren, indem ich toDataURL für das zurückgegebene canvas . Aber die Qualität des Bildes ist eher unscharf/schlecht. Ich habe etwas gegoogelt und herausgefunden, dass standardmäßig nur ein Bild mit 96 dpi zurückgegeben wird. Und es scheint keine Standardmethode zu geben, dies zu verbessern. Auch das toDataURLHD ist experimentell und funktioniert in keiner Weise.

Gibt es eine Möglichkeit, html2canvas ein Bild mit einer höheren Auflösung zurückzugeben? Oder selbst wenn es eine Möglichkeit bietet, das DOM zu rendern, kann ich eine Bibliothek verwenden, die das DOM verwendet (mit allen darauf angewendeten berechneten Stilen) und dann jedes gewünschte Bild generieren.

Hilfreichster Kommentar

+1 dafür. Sie möchten ein Bild mit html2canvas zum Einfügen in ein PDF erhalten, erhalten jedoch eine verschwommene Qualität.

Alle 58 Kommentare

Ich weiß, dass irgendwann in anderen Issues/Requests darüber gesprochen wurde und jemand einen Pull-Request eingereicht hatte, aber ich habe nie gesehen, dass die Pull-Requests zusammengeführt wurden.

Ich habe eine Arbeitsmethode, mit der wir die Pixeldichte des Geräts überprüfen. Aber das kann die Leistung beeinträchtigen. Stattdessen möchten wir vielleicht einen Parameter haben, der anweist, mit höheren dpi zu rendern?

@missing Ja, ein Parameter zur Angabe der DPI wäre großartig.

Auch wenn es Ihnen nichts ausmacht, die Arbeitsmethode für die Pixeldichte des Geräts zu teilen, ist das cool. Meine Hauptanwendung besteht darin, einfach ein PNG einer Wortwolke mit maximal 50 Begriffen zu exportieren. Ich bin also nicht allzu besorgt über den Performance-Hit in diesem Fall.

Ist es Ihr Problem, ist die Qualität des Bildes oder ist ein verschwommener Effekt (in einigen Fällen werden einige Bilder von html2canvas mit verschwommenem Effekt erzeugt)?

@brcontainer Ich denke, die Qualität des Bildes ist das Problem. Ich denke. ZB bei 100% Zoom sieht das Foto ok-anständig-ish aus. Aber sobald ich sogar 5 % zoome, kann man einen deutlichen Qualitätsverlust des Fotos feststellen. Siehe angehängtes Bild.
association-cloud-apple-twitter

Ich kann mir nur sicher sein, dass etwas ein Beispiel für das Problem zur Laufzeit sieht.

Versuchen Sie es an derselben Stelle mit http://jsfiddle.net/ und posten Sie den Link hier.

[bearbeiten]
Wenn Sie versuchen, _zoom_ in einer von html2canvas generierten Leinwand anzuwenden, können Sie versuchen, Folgendes zu verwenden (vor dem Speichern als Bild):

ctx.webkitImageSmoothingEnabled = false;
ctx.mozImageSmoothingEnabled = false;
ctx.imageSmoothingEnabled = false;

Viel Glück

Hi,

Wir brauchen eine höhere Auflösung als 96DPI. Wir brauchen mehr wie 300 DPI.

Hat das überhaupt _möglich_ mit html2canvas zu tun?

Wir haben das gleiche Problem mit der Unschärfe im Bild. Wir brauchen eine Lösung, die unsere Unschärfe beseitigt und uns einen DPI gibt, der gut aussieht.

Irgendwelche Gedanken/Vorschläge, wie dies geschehen könnte, oder alternative Möglichkeiten, um den gleichen Effekt zu erzielen?

Vielen Dank

@brcontainer Ich habe jetzt gerade deine Bearbeitung. Ich habe getan, was Sie vorgeschlagen haben, und immer noch kein Glück mit der Bildqualität. Hier ist, was ich getan habe -

                var ctx = canvas.getContext('2d');

                ctx.webkitImageSmoothingEnabled = false;
                ctx.mozImageSmoothingEnabled = false;
                ctx.imageSmoothingEnabled = false;

                var rawData = canvas.toDataURL("image/png");

in der falschen Reihenfolge ist, müssen Sie "ImageSmoothingEnabled" anwenden, bevor Sie die Größe des Bildes ändern.

Fügen Sie ein Beispiel Ihres Codes in http://jsfiddle.net ein und ich werde versuchen, ihn zu bearbeiten

Hallo Leute,

Ich möchte hochauflösende Bilder ohne die 96dpi-Beschränkung von toDataURL hochladen. Da toDataURLHD noch nicht verfügbar ist, wie kann ich meinen Traum verwirklichen? :-)

Danke im Voraus für jeden Hinweis

@brcontainer Ich bin mir nicht sicher, ob ich verstehe, was Sie mit dem Anwenden der Glättung vor der Größenänderung meinen, da ich das Bild überhaupt nicht skaliere. Auf jeden Fall habe ich eine jsfiddle für Sie erstellt, die Sie sich ansehen können http://jsfiddle.net/tankchintan/92mra/4/

Freue mich schon sehr, das gelöst zu bekommen! :)

Freund, Sie sind verwirrend, es gibt das toDataURL , das die Größe ändern muss, Sie müssen die Größe des CANVAS ändern.
Ich versuche, ein Beispiel zu erstellen, konnte es aber immer noch nicht zum Laufen bringen.

Hi,

Ich habe versucht, diesen Vorschlägen für eine bessere Bildqualität zu folgen, und es ist mir auch nicht klar.

brcontainer, ist es möglich, dass Sie eine von Tankchintan erstellte JS-Geige mit den Ideen, von denen Sie sprechen, klären oder ändern / erstellen? Dies macht für mich keinen Sinn, selbst wenn wir ein Bild mit 2x der Größe erstellen, bleibt die Pixelierung im Bild immer noch erhalten, nachdem wir das Bild auf 192 DPI konvertiert haben.

Hallo Leute, gibt es noch mehr Feedback zu diesem Thema? Ich erlebe mit html2canvas eine extrem professionelle Bildqualität im Vergleich zu etwas wie PhantomJS, bei dem Sie zoomFactor (unter anderem) einstellen können, um die Qualität/Auflösung zu erhöhen.

Ich habe ein ähnliches Problem. Ich muss einen Schnappschuss der Webseite in ein PDF-Dokument erstellen, für das ich html2canvas verwende, um mein Div in ein Bild zu konvertieren, und dann verwende ich iTextsharp, um das Bild zu einem PDF hinzuzufügen. Allerdings wirkt das erzeugte Bild etwas unscharf und erschwert es dem Auge, es ständig zu betrachten. Ich möchte wissen, ob ich ein Bild der angegebenen Auflösung zum Zeitpunkt der Erstellung selbst in html2canvas erstellen kann.

Hi,
Ich habe genau die gleiche Anforderung wie oben. und das gleiche Problem habe ich.
"Erhalte einen Schnappschuss der Webseite in ein PDF-Dokument, für das ich html2canvas verwende, um mein div in ein Bild umzuwandeln und das Bild dann zu einem PDF hinzuzufügen."
Allerdings erscheint das erzeugte Bild etwas unscharf.

Ich habe die obigen Vorschläge befolgt, aber trotzdem bekomme ich ein verschwommenes Bild.
hier in meinem Code: html2canvas generiert einen Snapshot der Webseite basierend auf der Systemauflösung.
Ich erhalte denselben Webseiten-"Schnappschuss" in verschiedenen Größen, basierend auf der Systemauflösung.

Beispiel :
Bildgröße: 816x422
Bildgröße: 1193x437
Bildgröße: 1275x437
Hier ist meine Erwartung: 2000 x 1784 Dimension und höher.

ist es möglich, diese Dimension des Bildes zu erhalten.
Bitte geben Sie Ihre wertvollen Anregungen und danke für Ihre wertvolle Zeit.

+1 dafür. Sie möchten ein Bild mit html2canvas zum Einfügen in ein PDF erhalten, erhalten jedoch eine verschwommene Qualität.

Haben Sie versucht, die CSS-Transformationsmatrix auf einem parentNode für das Element zu verwenden, das Sie mit einer höheren Auflösung exportieren möchten? Das funktioniert bei mir. ZB "transformieren: scale(2, 2)"

@mudcube hat teilweise für mich

@brcontainer bei mir einwandfrei

gibt es eine lösung gefunden?? Bitte teilen Sie uns mit, wie Sie die Auflösung eines verschwommenen Bildes verbessern können. Ich muss ein PDF davon erstellen

+1 Gibt es dafür schon eine Lösung/Richtlinie?

irgendeine lösung gefunden?

Leute, benutze transform: scale(2, 2) es funktioniert.

Können Sie nähere Angaben machen?

@matiasinsaurralde füge direkt vor dem Screenshot die CSS-Klasse .x2 die CSS-Regel von oben zum Element enthält, und entferne dann diese Klasse im html2canvas Callback. Sie erhalten auch ein Element in doppelter Größe und einen Screenshot in doppelter Größe. Und es ist nahtlos, sodass Sie wahrscheinlich keine Größenänderungen feststellen werden.

image
Screenshot, als ich versuchte, deinem Vorschlag

Scale hat die Auflösung für mich nicht erhöht. Musste es mit JS lösen -
https://github.com/niklasvh/html2canvas/issues/379

Irgendein Glück, Jungs?

transform: scale(2, 2); ist auch nicht die Lösung für dygraph.js

@premerddyn , siehe meine Lösung im verlinkten Problem.
Es funktioniert gut, erfordert jedoch eine Vergrößerung vor dem Screenshot.
Wenn mein Kommentar nicht klar ist, füge ich weitere Erklärungen hinzu

Nun, was ich getan hatte, war ein Div mit doppelter Größe zu erstellen und die Sichtbarkeit zusammenbrechen zu lassen und jeden Inhalt, den ich hier hatte, habe ich zu diesem Div gepostet und einen Screenshot gemacht Arbeit.Ich bekomme das funktioniert.Aber mein Problem ist mit Textstrich und mehrzeiligem Texthintergrund.

Die Skalierung um 2 funktioniert bei mir, ich finde jedoch, dass das Rendering durch die Fensterauflösung / -größe begrenzt ist. Wenn das skalierte div breiter als das Fenster ist, wird ein Teil davon abgeschnitten

Gibt es also keine Möglichkeit, Leinwände aufzunehmen, die größer als der Bildschirm sind?

Ach, aus diesem Thread:

var h = $(element)[0].ownerDocument.defaultView.innerHeight;
    $(element)[0].ownerDocument.defaultView.innerHeight = $(element).height();
    html2canvas($(element)).then(function(canvas) {
        $(element)[0].ownerDocument.defaultView.innerHeight = h;
        //Do whatever you want with your canvas
    }

https://jsfiddle.net/enjoythedaycsk/9L966sdd/1/

Ich habe versucht, in diesem Beispiel eine hohe Auflösung zu erreichen, aber das habe ich nicht bekommen ...

Klicken Sie auf die Schaltfläche pngx2 herunterladen..

Ist es möglich, Operationen im Backend durchzuführen, wie wenn die Schaltfläche angeklickt wird, wird die Leinwand auf die doppelte Größe vergrößert und dann wird das Bild aufgenommen und dann wird die Leinwand wieder auf die normale Größe zurückgesetzt.

Klar, das könntest du machen. Ich triggere eine Leinwand in der gewünschten Größe mit dem
Code zur Verfügung gestellt. Ich habe festgestellt, dass das Abrufen des Werts ungenau sein kann, also habe ich einfach
Breite/Höhe direkt einstellen.

Am Samstag, 7. Mai 2016, hat enjoytheday [email protected] geschrieben:

https://jsfiddle.net/enjoythedaycsk/9L966sdd/1/

Ich habe versucht, in diesem Beispiel eine hohe Auflösung zu erreichen, habe es aber nicht geschafft
das...

Klicken Sie auf die Schaltfläche pngx2 herunterladen..

Ist es möglich, Operationen im Backend durchzuführen, wie wenn die Schaltfläche angeklickt wird?
Leinwand wird doppelt so groß und dann wird das Bild aufgenommen und dann wieder
Leinwand wird wieder auf normale Größe gebracht..


Sie erhalten dies, weil Sie einen Kommentar abgegeben haben.
Antworten Sie direkt auf diese E-Mail oder zeigen Sie sie auf GitHub an
https://github.com/niklasvh/html2canvas/issues/241#issuecomment -217634634

Die längste fortlaufende Illustration der Welt
ForeverScape.com http://www.foreverscape.com/ | @foreverscape
https://twitter.com/foreverscape | Auf Github
https://github.com/vance/foreverscapecore | In den Nachrichten
http://www.foreverscape.com/art/reviews/

@vance können Sie dies bitte im jsfiddle-Beispiel einstellen?

https://jsfiddle.net/enjoythedaycsk/9L966sdd/1/

Ich habe es versucht, aber es wird nicht von mir eingestellt.

Sie können es vollständig bearbeiten oder neu erstellen.

Es wird für viele hilfreich sein :Tänzer:

Ich habe versucht, es schnell zu verspotten, hatte aber keine Zeit, das Test-Div zu reparieren. Etwas mit transform:scale() einzufangen bringt nichts, da die interne Höhe des div _NICHT_ beeinflusst wird. Deshalb ist es eine Transformation. Seine Eigenschaften sind unverändert (intern), was Sie testen können, indem Sie getBoundingClientRect() . Seine Breite/Höhe ändert sich nur _tatsächlich_, wenn es im Kontext des übergeordneten Elements angezeigt wird. Sie müssen das Container-Div greifen, nachdem es skaliert wurde.

https://jsfiddle.net/jano9ao4/1/

Ich stehe vor dem gleichen Problem, gibt es eine praktikable Lösung?ヾ(´・ ・`。)ノ"

Ich konnte es zum Laufen bringen, um Elemente einzufangen, die größer als das Fenster waren. Denken Sie daran, dass Sie nicht einfach von einem transformierten Element ein "größeres" Bild erhalten können, da es (für sich selbst) immer noch die gleichen Abmessungen hat.

Ich musste meine in einem iframe machen und die base64-Daten als Nachricht zurücksenden ... weil das folgende BREAKS das Fenstergrößenänderungsereignis durchführte.

Nochmal mit Kommentaren:

   //store the original size
    var h = $(element)[0].ownerDocument.defaultView.innerHeight;
    var w = $(element)[0].ownerDocument.defaultView.innerWidth;

   //set the document to the element's size
    $(element)[0].ownerDocument.defaultView.innerHeight = $(element).height();
    $(element)[0].ownerDocument.defaultView.innerWidth = $(element).width();

    html2canvas($(element)).then(function(canvas) {
        //restore the document size
        $(element)[0].ownerDocument.defaultView.innerHeight = h;
        $(element)[0].ownerDocument.defaultView.innerWidth = w;
        //Do whatever you want with your canvas
    }

Ich habe die folgende Funktion geschrieben, um mit html2canvas einfach einen Screenshot mit höherer DPI von einem HTML-Element zu erhalten.

  • wenn die Höhe oder Breite eingeschränkt ist (z. B. eine feste Körperbreite vorhanden ist), müssen die Einschränkungen während der Verarbeitung entfernt werden - das Quellelement muss in der Lage sein, auf den gewünschten Maßstab zu wachsen
  • srcEl sollte ein vorhandenes Element sein
  • destIMG sollte ein vorhandenes (leeres) Bildelement sein
  • dpi sollte ein Vielfaches von 96 sein
var makeHighResScreenshot = function(srcEl, destIMG, dpi) {
    var scaleFactor = Math.floor(dpi / 96);
    // Save original size of element
    var originalWidth = srcEl.offsetWidth;
    var originalHeight = srcEl.offsetHeight;
    // Save original document size
    var originalBodyWidth = document.body.offsetWidth;
    var originalBodyHeight = document.body.offsetHeight;

    // Add style: transform: scale() to srcEl
    srcEl.style.transform = "scale(" + scaleFactor + ", " + scaleFactor + ")";
    srcEl.style.transformOrigin = "left top";

    // create wrapper for srcEl to add hardcoded height/width
    var srcElWrapper = document.createElement('div');
    srcElWrapper.id = srcEl.id + '-wrapper';
    srcElWrapper.style.height = originalHeight*scaleFactor + 'px';
    srcElWrapper.style.width = originalWidth*scaleFactor + 'px';
    // insert wrapper before srcEl in the DOM tree
    srcEl.parentNode.insertBefore(srcElWrapper, srcEl);
    // move srcEl into wrapper
    srcElWrapper.appendChild(srcEl);

    // Temporarily remove height/width constraints as necessary
    document.body.style.width = originalBodyWidth*scaleFactor +"px";
    document.body.style.height = originalBodyHeight*scaleFactor +"px";

    window.scrollTo(0, 0); // html2canvas breaks when we're not at the top of the doc, see html2canvas#820
    html2canvas(srcElWrapper, {
        onrendered: function(canvas) {
            destIMG.src = canvas.toDataURL("image/png");
            srcElWrapper.style.display = "none";
            // Reset height/width constraints
            document.body.style.width = originalBodyWidth + "px";
            document.body.style.height = originalBodyHeight + "px";
        }
    });
};

Verwendungszweck:

var src = document.getElementById("screenshot-source");
var img = document.getElementById("screenshot-img");
makeHighResScreenshot(src, img, 192); // DPI of 192 is 4x resolution (2x normal DPI for both width and height)

Haben Sie festgestellt, dass dadurch auch window.onresize-Ereignishandler beschädigt werden? Aus diesem Grund musste ich all dies in einem iframe tun und das Ergebnis mit parent.window.postMessage(data) zurückgeben, um den Inhalt zurückzugeben. Dies ist nur für mich wichtig, weil es sich um eine mobile App handelt und es wichtig ist, das Feuer in der Größe zu ändern.

@vance : In meinem Fall brauche oder verwende ich keines dieser Dinge - ich verwende dies tatsächlich, um einen Fehler in einem HTML-to-PDF-Renderer zu umgehen. Ich würde gerne ein vollständiges Beispiel für Ihre Methode sehen, es scheint flexibler zu sein.

Ich habe einen anderen Weg gefunden, um ein hochauflösendes Bild zu erhalten, bei dem die Größe des Körpers nicht geändert werden muss. Aufgrund eines Fehlers in html2canvas (#790, #820, #893, #922 usw.) muss das Quellelement jedoch absolut positioniert werden. Basierend auf dem Retina-Code von @MisterLamb .

function takeHighResScreenshot(srcEl, destIMG, scaleFactor) {
    // Save original size of element
    var originalWidth = srcEl.offsetWidth;
    var originalHeight = srcEl.offsetHeight;
    // Force px size (no %, EMs, etc)
    srcEl.style.width = originalWidth + "px";
    srcEl.style.height = originalHeight + "px";

    // Position the element at the top left of the document because of bugs in html2canvas. The bug exists when supplying a custom canvas, and offsets the rendering on the custom canvas based on the offset of the source element on the page; thus the source element MUST be at 0, 0.
    // See html2canvas issues #790, #820, #893, #922
    srcEl.style.position = "absolute";
    srcEl.style.top = "0";
    srcEl.style.left = "0";

    // Create scaled canvas
    var scaledCanvas = document.createElement("canvas");
    scaledCanvas.width = originalWidth * scaleFactor;
    scaledCanvas.height = originalHeight * scaleFactor;
    scaledCanvas.style.width = originalWidth + "px";
    scaledCanvas.style.height = originalHeight + "px";
    var scaledContext = scaledCanvas.getContext("2d");
    scaledContext.scale(scaleFactor, scaleFactor);

    html2canvas(srcEl, { canvas: scaledCanvas })
    .then(function(canvas) {
        destIMG.src = canvas.toDataURL("image/png");
        srcEl.style.display = "none";
    });
};

Verwendungszweck:

var src = document.getElementById("screenshot-src");
var img = document.getElementById("screenshot-img");
takeHighResScreenshot(src, img, 2); // This time we provide desired scale factor directly, no more messing with DPI

BEARBEITEN: Reduzierte Hackiness durch absolute Positionierung, anstatt das Element tatsächlich zu verschieben und die Ränder anzupassen, dank @jason-o-matic für den Vorschlag.

dies funktioniert mit der neuesten Version (0.5.0-alpha). aber nicht 0.4.1

Wenn Sie dieses Problem in 0.4.1 lösen möchten, müssen Sie mit der Leinwandgröße herumspielen.

Nur eine kurze Anmerkung für alle, die den @airdrummingfool verwenden (der großartig funktioniert) ...

Sie können keine "relativen" Elemente haben, die das Element umschließen, das Sie im Bildschirmauszug erstellen möchten, egal wie weit sie sich im Xtree befinden. Sie müssen für die Dauer des Screendumps auf statisch geschaltet werden, damit das gewünschte Element tatsächlich bei 0,0 relativ zum Fenster angezeigt wird, nicht um ein umgebendes DIV.

Ich habe mehrere Stunden gebraucht, um dies herauszufinden, daher hoffe ich, dass dies jemandem hilft, die gleichen Probleme zu vermeiden.

Guten nachmittag Leute,
Hat jemand eine jsfiddle von @airdrummingfool- Lösung, ich versuche, sie ohne

Vielen Dank für jede Hilfe, die bereitgestellt werden kann.

Hallo allerseits! Ich versuche, die @airdrummingfool- Lösung zu verwenden. Aber ich bekomme einen nervigen Fehler. Innerhalb des Elements, von dem ich das Bild erhalten möchte, befindet sich a -Element und wenn die Prozedur ausgeführt wird, wird das img-Element leer und der src wird ignoriert. Wisst ihr wie ich das lösen kann? Hat jemand dieses Problem schon einmal mit html2canvas konfrontiert?

Danke im Voraus an diesen Thread! Es rettet mich!! :D

EDIT: Ich bekomme auch nur die Hälfte des gerenderten Bildes. Aber Auflösung sieht perfekt aus xD

Bildproblem behoben!! Der useCORS wurde nicht aktiviert! Aber ich bekomme immer noch nur die Hälfte des gerenderten Bildes.

Groß! Das Halbbild kann auf das Problem beim um html2canvas Auflösung/Skalierung hinzuzufügen . Sie finden es möglicherweise einfacher zu verwenden als die @airdrummingfool- Lösung.

Bis denjenigen erhalten , um html2canvas verschmolzen, können Sie meine Maßarbeit mit diesen beiden und ein paar anderen Fehlerbehebung erhalten hier .

Hallo @eKoopmans. Danke für deine Antwort. Ich habe es gerade geschafft, meine zu reparieren, indem ich die Höhe mit 2 multipliziert habe. Aber ich denke, ich bekomme ein größeres Bild mit weißen Flächen oben und unten... !

OM(F)G @eKoopmans .. Dein Werk ist

Schluss zu Gunsten von #1087

@airdrummingfool ... Danke. Das funktioniert perfekt.

Die neueste Version von html2canvas bietet Ihnen eine Skalierungsoption. Funktioniert wirklich gut.

html2canvas(element, {
Maßstab: 2
});

Beim mehrseitigen PDF-Rendering von HTML- und Bildinhalten kann die Einstellung von scale: 1 das Auflösungsproblem beheben und gleichzeitig vermeiden, dass Bilder den PDF-Rahmen überschreiten.

Ich denke, das hilft, ich habe html2canvas verwendet

PDF Herunterladen() {
var doc = neues jsPDF({
Format: "a4"
});

html2canvas(document.getElementById("pdf-doc"), {
Skala: "5"
}).then(Leinwand => {
this.imgFile = Leinwand;
doc.addImage(this.imgFile, "JPEG", 5, 5, 200, 285);
doc.save("Dateiname" + ".pdf");
});
}

War diese Seite hilfreich?
0 / 5 - 0 Bewertungen