Html2canvas: Moyen d'augmenter la résolution de l'image générée via toDataURL

Créé le 10 juil. 2013  ·  58Commentaires  ·  Source: niklasvh/html2canvas

Il s'agit plus d'une demande de fonctionnalité. Je peux facilement générer le PNG en appelant toDataURL sur le canvas renvoyé. Mais la qualité de l'image est plutôt floue/médiocre. J'ai fait quelques recherches sur Google et j'ai découvert que par défaut, il ne renvoie qu'une image à 96 dpi. Et il ne semble pas y avoir de moyen standard d'améliorer cela. De plus, le toDataURLHD est expérimental et ne fonctionne en aucun cas.

Existe-t-il un moyen pour html2canvas renvoyer une image à une résolution plus élevée ? Ou même si cela peut fournir un moyen d'obtenir le rendu du DOM, je peux utiliser une bibliothèque qui utilise le DOM (avec tous les styles calculés qui lui sont appliqués), puis générer l'image que je veux.

Commentaire le plus utile

+1 pour cela. Vous cherchez à obtenir une image avec html2canvas à insérer dans un PDF, mais avec une qualité floue.

Tous les 58 commentaires

Je sais qu'il en a été question à un moment donné dans d'autres problèmes/demandes et que quelqu'un avait soumis une demande de tirage, mais je n'ai jamais vu les demandes de tirage fusionnées.

J'ai une méthode de travail que nous utilisons pour vérifier la densité de pixels de l'appareil. Mais cela peut avoir un impact sur les performances. Au lieu de cela, nous voulons peut-être avoir un paramètre pour lui dire de s'afficher avec une résolution plus élevée ?

@missing Ouais, un paramètre pour spécifier le DPI serait génial.

De plus, si cela ne vous dérange pas de partager la méthode de travail pour la densité de pixels de l'appareil, ce sera cool. Mon application principale consiste simplement à exporter un png d'un nuage de mots de 50 termes maximum. Je ne suis donc pas trop préoccupé par les performances de celui-ci.

Est-ce que votre problème est la qualité de l'image ou est-ce un effet flou (dans certains cas, certaines images sont générées par html2canvas avec un effet flou) ?

@brcontainer Je pense que la qualité de l'image est le problème. Je pense. Par exemple, avec un zoom à 100%, la photo semble correcte. Mais dès que je zoome même 5%, vous pouvez voir une baisse notable de la qualité de la photo. S'il vous plaît voir l'image ci-jointe.
association-cloud-apple-twitter

Je ne peux être sûr que de quelque chose en voyant un exemple du problème au moment de l'exécution.

Essayez le même endroit en utilisant http://jsfiddle.net/ et publiez le lien ici.

[Éditer]
si vous essayez d'appliquer _zoom_ dans un canevas généré par html2canvas, vous pouvez essayer d'utiliser (avant d'enregistrer en tant qu'image):

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

Bonne chance

Salut,

Nous avons besoin d'une résolution supérieure à 96DPI. Nous avons besoin de plus de 300 DPI.

Est-ce même _possible_ à voir avec html2canvas ?

Nous avons le même problème avec le flou sur l'image. Nous avons besoin de n'importe quelle solution qui supprimera notre flou et nous donnera un DPI qui semble bon.

Avez-vous des idées/suggestions sur la façon dont cela pourrait être fait, ou d'autres moyens d'obtenir le même effet ?

Merci

@brcontainer Je viens de modifier maintenant. J'ai fait ce que vous avez suggéré et toujours pas de chance avec la qualité d'image. Voici ce que j'ai fait -

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

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

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

est dans le mauvais ordre, vous devez appliquer "ImageSmoothingEnabled" avant de redimensionner l'image.

Mettez un échantillon de votre code dans http://jsfiddle.net et j'essaierai de le modifier

Salut les gars,

Je souhaite télécharger des images haute résolution sans la contrainte 96dpi de toDataURL. Puisque toDataURLHD n'est pas encore disponible, comment puis-je réaliser mon rêve ? :-)

Merci d'avance pour toute astuce

@brcontainer Je ne suis pas sûr de comprendre ce que vous entendez par appliquer le lissage avant le redimensionnement, car je ne redimensionne pas du tout l'image. Dans tous les cas, j'ai créé un jsfiddle pour que vous puissiez regarder http://jsfiddle.net/tankchintan/92mra/4/

J'ai vraiment hâte de régler ça ! :)

Ami vous confondez, il y a le toDataURL qui doit redimensionner, vous devez redimensionner le CANVAS .
J'essaie de créer un exemple, mais je n'arrive toujours pas à le faire fonctionner.

Salut,

J'ai essayé de suivre ces suggestions pour une meilleure qualité d'image, et ce n'est pas clair pour moi non plus.

brcontainer, est-il possible que vous puissiez clarifier, ou modifier/créer un violon JS que tankchintan a créé, avec les idées dont vous parlez ? Cela n'a aucun sens pour moi, même si nous créons une image à 2 fois la taille, la pixellisation de l'image reste toujours après avoir converti l'image en 192 DPI.

Salut les gars, y a-t-il d'autres retours sur ce problème ? J'ai une qualité d'image extrêmement pro avec html2canvas par rapport à quelque chose comme PhantomJS où vous pouvez définir zoomFactor (entre autres réglages) pour augmenter la qualité/résolution.

J'ai un problème similaire. J'ai besoin d'obtenir un instantané de la page Web dans un document PDF pour lequel j'utilise html2canvas pour convertir mon div en une image, puis j'utilise iTextsharp pour ajouter l'image à un PDF. Cependant, l'image générée semble être un peu floue et rend difficile pour l'œil de la voir constamment. Je veux savoir si je peux créer une image de résolution spécifiée au moment de la création lui-même dans html2canvas.

Salut,
J'ai exactement la même exigence que ci-dessus. et même problème auquel je suis confronté.
"Obtenir un instantané de la page Web dans un document PDF pour lequel j'utilise html2canvas pour convertir mon div en une image, puis ajouter l'image à un PDF."
Cependant, l'image générée semble être un peu floue.

J'ai suivi les suggestions ci-dessus, mais j'obtiens toujours une image floue.
ici dans mon code: html2canvas génère un instantané de la page Web basé sur la résolution du système.
Je reçois le même "instantané" de page Web dans différentes tailles, en fonction de la résolution du système.

Exemple :
taille de l'image : 816x422
taille de l'image:1193x437
taille de l'image : 1275x437
Ici, mon attente est : 2000 x 1784 Dimension et plus.

est-il possible d'obtenir cette dimension d'image.
s'il vous plaît donner vos précieuses suggestions et merci pour votre temps précieux.

+1 pour cela. Vous cherchez à obtenir une image avec html2canvas à insérer dans un PDF, mais avec une qualité floue.

Avez-vous essayé d'utiliser la matrice de transformation CSS sur un parentNode vers l'élément que vous souhaitez exporter à une résolution plus élevée ? Cela fonctionne pour moi. Par exemple "transformer : échelle(2, 2)"

@mudcube a fonctionné en partie pour moi

@brcontainer ça marche bien pour moi

y a t'il une solution trouvée ?? s'il vous plaît partager comment améliorer la résolution de l'image floue je dois en faire un pdf

+1 existe-t-il encore une solution/une directive pour cela ?

une solution trouvée ?

Les gars, utilisez transform: scale(2, 2) ça marche.

Pouvez-vous fournir plus de détails?

@matiasinsaurralde juste avant de faire une capture d'écran, ajoutez la classe CSS .x2 contenant la règle CSS ci-dessus à l'élément, puis supprimez cette classe dans le rappel html2canvas . Vous obtiendrez également un élément de taille double et une capture d'écran de taille double. Et il est transparent, vous n'observerez donc probablement aucun redimensionnement.

image
capture d'écran lorsque j'ai essayé de suivre votre suggestion @Ajaxy . Je pense que le problème vient de mon code ? il a fallu tellement de temps pour rendre la page

l'échelle n'a pas augmenté la résolution pour moi. J'ai dû le résoudre avec JS -
https://github.com/niklasvh/html2canvas/issues/379

Un peu de chance les gars ?

transform: scale(2, 2); n'est pas non plus la solution pour dygraph.js

@premerddyn , voir ma solution dans le problème lié.
Cela fonctionne bien, mais nécessite un agrandissement avant la capture d'écran.
Si mon commentaire n'est pas clair, j'ajouterai plus d'explications

eh bien, ce que j'avais fait, c'est de créer un div de taille double et de réduire la visibilité et chaque contenu que j'avais ici, j'ai posté sur ce div et pris une capture d'écran. De cette façon, aucune clarté d'image n'est perdue et j'ai modifié un code de taille de police pour le faire work.I get this work fine.Mais mon problème est avec le texte et l'arrière-plan du texte multiligne.

la mise à l'échelle par 2 fonctionne pour moi, cependant, je trouve que le rendu est limité par la résolution/taille de la fenêtre. Si le div mis à l'échelle est plus large que la fenêtre, une partie sera coupée

alors, n'y a-t-il aucun moyen de capturer des toiles plus grandes que l'écran ?

Ah, de ce fil :

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/

J'ai essayé d'obtenir une haute résolution dans cet exemple, mais je n'ai pas obtenu cela ...

Cliquez sur le bouton télécharger pngx2..

Est-il possible d'effectuer des opérations sur le backend, comme lorsque le bouton est cliqué, le canevas devient deux fois sa taille, puis l'image est capturée, puis le canevas est ramené à sa taille normale.

Bien sûr, vous pourriez le faire. Je déclenche une toile de la taille que je veux en utilisant le
code fourni. J'ai trouvé que l'obtention de la valeur peut être inexacte, alors j'ai juste
régler directement la largeur/hauteur.

Le samedi 7 mai 2016, enjoytheday [email protected] a écrit :

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

J'ai essayé d'obtenir une haute résolution dans cet exemple mais je n'ai pas obtenu
cette...

Cliquez sur le bouton télécharger pngx2..

Est-il possible d'effectuer des opérations sur le backend comme lorsque le bouton est cliqué
la toile se transforme en deux fois sa taille, puis la photo est capturée, puis à nouveau
la toile est ramenée à sa taille normale.

-
Vous recevez ceci parce que vous avez commenté.
Répondez directement à cet e-mail ou consultez-le sur GitHub
https://github.com/niklasvh/html2canvas/issues/241#issuecomment -217634634

L'illustration en cours la plus longue au monde
ForeverScape.com http://www.foreverscape.com/ | @foreverscape
https://twitter.com/foreverscape | Sur Github
https://github.com/vance/foreverscapecore | Dans les nouvelles
http://www.foreverscape.com/art/reviews/

@vance pouvez-vous s'il vous plaît définir ceci dans l'exemple jsfiddle ?

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

J'ai essayé mais ce n'est pas réglé par moi.

Vous pouvez le modifier complètement ou en créer un nouveau.

Cela sera utile à beaucoup :danseur:

J'ai essayé de le faire rapidement mais je n'ai pas eu le temps de réparer le div de test. Capturer quelque chose avec transform:scale() ne fait rien car la hauteur interne du div n'est _PAS_ affectée. C'est pourquoi c'est une transformation. Ses propriétés w/h sont inchangées (en interne), que vous pouvez tester en obtenant getBoundingClientRect() . Sa largeur/hauteur ne change _réellement_ que lorsqu'elle est vue dans le contexte du parent. Vous devez saisir le conteneur div après sa mise à l'échelle.

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

Je suis confronté au même problème, existe-t-il une solution viable ?ヾ(´・ ・`。)ノ"

J'ai pu le faire fonctionner, capturer des éléments plus grands que la fenêtre. N'oubliez pas que vous ne pouvez pas obtenir une image "plus grande" simplement à partir d'un élément transformé, car (pour lui-même), il a toujours les mêmes dimensions.

J'ai dû faire le mien dans un iframe et renvoyer les données base64 sous forme de message ... car faire ce qui suit ARRÊTE l'événement de redimensionnement de la fenêtre.

Encore avec des commentaires :

   //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
    }

J'ai écrit la fonction suivante pour obtenir facilement une capture d'écran à résolution plus élevée à partir d'un élément HTML à l'aide de html2canvas.

  • si la hauteur ou la largeur est limitée (par exemple, il existe une largeur de corps fixe), les contraintes doivent être supprimées pendant le traitement - l'élément source doit pouvoir atteindre l'échelle souhaitée
  • srcEl doit être un élément existant
  • destIMG doit être un élément d'image existant (vide)
  • dpi doit être un multiple de 96
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";
        }
    });
};

Usage:

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)

Avez-vous constaté que cela interrompt également les gestionnaires d'événements window.onresize ? Pour cette raison, j'ai dû faire tout cela dans un iframe et poster le résultat en utilisant parent.window.postMessage(data) pour renvoyer le contenu. Cela n'a d'importance que pour moi car il s'agit d'une application mobile et il est essentiel de redimensionner le feu.

@vance : Dans mon cas, je n'ai besoin ni n'utilise aucune de ces choses - je l'utilise en fait pour contourner un bogue dans un moteur de rendu HTML vers PDF. J'aimerais voir un exemple complet de votre méthode, elle semble plus flexible.

J'ai trouvé un autre moyen d'obtenir une image haute résolution qui n'a pas besoin de redimensionner le corps. Cependant, il doit absolument positionner l'élément source en raison d'un bug dans html2canvas (#790, #820, #893, #922, etc). Basé sur le code rétine de @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";
    });
};

Usage:

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

EDIT : Réduction du piratage en utilisant le positionnement absolu au lieu de déplacer réellement l'élément et d'ajuster les marges, grâce à @jason-o-matic pour la suggestion.

cela fonctionne avec la dernière version (0.5.0-alpha). mais pas 0.4.1

si vous voulez résoudre ce problème dans la 0.4.1, vous devez jouer avec la taille du canevas.

Juste un petit mot pour tous ceux qui utilisent le correctif de

Vous ne pouvez pas avoir d'éléments « relatifs » enveloppant l'élément que vous souhaitez vidage d'écran, quelle que soit la hauteur de l'arbre x. Ils doivent être commutés en statique pendant la durée du vidage d'écran afin que l'élément souhaité apparaisse réellement à 0,0 par rapport à la fenêtre, et non à un DIV environnant.

Il m'a fallu plusieurs heures pour résoudre ce problème, alors j'espère que cela aidera quelqu'un à éviter les mêmes problèmes.

Bonne après midi les gars,
est-ce que quelqu'un a un jsfiddle de la solution @airdrummingfool , j'essaie de l'implémenter dans mon projet sans succès. Un exemple de travail serait formidable pour moi de comprendre comment cela fonctionne et m'aiderait beaucoup à essayer de le mettre en œuvre dans mon projet.

Merci beaucoup pour toute l'aide qui peut être fournie.

Salut à tous! J'essaie d'utiliser la solution @airdrummingfool . Mais j'obtiens une erreur ennuyeuse. À l'intérieur de l'élément dont je veux obtenir l'image, il y a un élément et lors de la procédure, l'élément img devient vide et le src est ignoré. Savez-vous comment puis-je résoudre cela? Quelqu'un a-t-il déjà rencontré ce problème avec html2canvas?

Merci d'avance pour ce fil ! ça me sauve !! :RÉ

EDIT : je n'obtiens également que la moitié de l'image rendue. Mais la résolution semble parfaite xD

Correction du problème d'image !! Le useCORS n'a pas été activé ! Mais je n'obtiens toujours que la moitié de l'image rendue.

Super! La demi-image peut être due au problème de rendu hors canevas . J'ai également fait une demande d'extraction pour ajouter la résolution/la mise à l'échelle à html2canvas , vous trouverez peut-être plus facile à utiliser que la solution @airdrummingfool .

Jusqu'à ce que ceux-ci soient fusionnés dans html2canvas, vous pouvez obtenir ma version personnalisée avec ces deux correctifs et quelques autres corrections de bugs ici .

Salut @eKoopmans. Merci pour votre réponse. J'ai juste réussi à réparer le mien en multipliant la hauteur par 2. Mais, je pense que j'obtiens une image plus grande avec des espaces blancs au-dessus et en dessous... alors... je vais essayer la vôtre et faire un rapport dans quelques minutes !

OM(F)G @eKoopmans .. Votre travail est

Clôture en faveur du #1087

@airdrummingfool ... Merci. Cela fonctionne parfaitement.

la dernière version de html2canvas vous offre une option de mise à l'échelle. Fonctionne vraiment bien.

html2canvas(élément, {
échelle : 2
});

Pour le rendu pdf de plusieurs pages à partir de contenu html et image, la définition de scale: 1 peut résoudre le problème de résolution et en même temps éviter que les images dépassent la bordure pdf.

Je pense que cela aide, j'ai utilisé html2canvas

Télécharger le PDF() {
var doc = nouveau jsPDF({
format : "a4"
});

html2canvas(document.getElementById("pdf-doc"), {
échelle : "5"
}).then(toile => {
this.imgFile = canevas;
doc.addImage(this.imgFile, "JPEG", 5, 5, 200, 285);
doc.save("nom de fichier" + ".pdf");
});
}

Cette page vous a été utile?
0 / 5 - 0 notes

Questions connexes

Loki180 picture Loki180  ·  4Commentaires

tibewww picture tibewww  ·  4Commentaires

deepender87 picture deepender87  ·  4Commentaires

koreanman picture koreanman  ·  4Commentaires

bishwapoudel picture bishwapoudel  ·  4Commentaires