2016-05-24 4 views
0

Je dois prendre une copie d'écran d'un div et ont besoin de l'envoyer au serveur (Java) à store.The code existant dans mon projet d'entreprise utilisé Html2Canvas.js où il devient l'élément (div, corps ...) et en retournant la base64 dataURI, il fonctionne très bien, mais geler l'application dans Chrome. Donc, je suis à la recherche d'une autre solution et trouvé le code ci-dessous de débordement de la pile.Comment obtenir dataURL de Blob ou BlobURL

var data = '<svg xmlns="http://www.w3.org/2000/svg" width="200" height="200">' + 
 
      '<foreignObject width="100%" height="100%">' + 
 
      '<div xmlns="http://www.w3.org/1999/xhtml" style="height:200px;width:200px;background-color:red;font-size:40px">' + 
 
      '<em></em> l ' + 
 
      '<span style="color:white; text-shadow:0 0 2px blue;">' + 
 
      '</span>' + 
 
      '</div>' + 
 
      '</foreignObject>' + 
 
      '</svg>'; 
 

 
var DOMURL = window.URL || window.webkitURL || window; 
 
var svg = new Blob([data], {type: 'image/svg+xml;charset=utf-8'}); 
 
var url = DOMURL.createObjectURL(svg); 
 
document.getElementById("image1").src=url;
<img id='image1' width="200px" height="200px"/>

Ici url je reçois est blob Url (blob: https% 3A // fiddle.jshell.net/a5b366a2-ff0c-4c7b-9b20-a80395d7f536) que je suis en mesure utiliser comme img src ou si j'ouvre directement l'URL dans un nouvel onglet, il est aussi l'ouverture. est-il de toute façon à obtenir les dataUri base64 comme celui-ci (données: image/png; base64, R0lGODlhEAAQAMQAAORHHOVSKudfOulrSOp3WOyDZu6QdvCchPGolfO0o/XB/fNwfjZ0frl3/zy7 //// waaaaa) à partir de l'URL de blob ou d'un objet blob?

Répondre

2

Vous pouvez utiliser FileReader et de le faire comme ceci:

var data = '<svg xmlns="http://www.w3.org/2000/svg" width="200" height="200">' + 
 
      '<foreignObject width="100%" height="100%">' + 
 
      '<div xmlns="http://www.w3.org/1999/xhtml" style="height:200px;width:200px;background-color:red;font-size:40px">' + 
 
      '<em></em> l ' + 
 
      '<span style="color:white; text-shadow:0 0 2px blue;">' + 
 
      '</span>' + 
 
      '</div>' + 
 
      '</foreignObject>' + 
 
      '</svg>'; 
 

 
var DOMURL = window.URL || window.webkitURL || window; 
 
var svg = new Blob([data], {type: 'image/svg+xml;charset=utf-8'}); 
 
var url = DOMURL.createObjectURL(svg); 
 

 
var base64data; 
 

 
var reader = new window.FileReader(); 
 
reader.readAsDataURL(svg); 
 
reader.onloadend = function() { 
 
    base64data = reader.result; 
 
    document.getElementById("image1").src=base64data; 
 
}
<img id='image1' width="200px" height="200px"/>

Documentation dit ceci au sujet readAsDataURL:

commence à lire le contenu du blob spécifié, une fois fini , l'attribut result contient une donnée: URL représentant les données du fichier.

+0

Ne créez pas une URL d'objet si vous ne l'utilisez pas, ce sont des cauchemars pour la mémoire. De plus, l'idée de l'utilisation de Blob par OP est une mauvaise idée pour svg. – Kaiido

+0

Vous avez raison sur vos deux déclarations. Le premier juste une erreur cependant - j'ai oublié là-bas. La seconde: répondre simplement à la question ... vous êtes gentil de le laisser savoir mieux avec une réponse si gentille :) – thepio

3

@thepio est juste sur la façon d'obtenir un dataURI d'un Blob: utiliser un FileReader et sa méthode readAsDataURL().
Cela vous donnera un base64 représentation dataURI du Blob/fichier.

Mais, nous allons jeter un recul par rapport à ce que vous faites:
Vous utilisez un pirater pour obtenir une sorte de capture d'écran de votre balisage HTML, SVG en utilisant de foreignObject.

Vous absolument ne pas besoin du Blob, ni la version base64 de le montrer dans un élément <img>:
Vous avez juste besoin de mettre l'en-tête de votre dataURI à 'data:image/svg+xml; charset=utf8, ' puis ajoutez votre balisage svg, cela permettra d'économiser jusqu'à à 30% de la taille des données.
Certains caractères doivent être codés, donc vous pouvez simplement appeler encodeURIComponent(yourSVGMarkup).

var svgString = '<svg xmlns="http://www.w3.org/2000/svg" width="200" height="200">' + 
 
    '<foreignObject width="100%" height="100%">' + 
 
    '<div xmlns="http://www.w3.org/1999/xhtml" style="height:200px;width:200px;background-color:red;font-size:40px">' + 
 
    '<em></em> l ' + 
 
    '<span style="color:white; text-shadow:0 0 2px blue;">' + 
 
    'I\'m white'+ 
 
    '</span>' + 
 
    '</div>' + 
 
    '</foreignObject>' + 
 
    '</svg>'; 
 

 
var dataURI = 'data:image/svg+xml; charset=utf8, ' + encodeURIComponent(svgString); 
 

 
img.src = dataURI;
<img id="img" />

Mais cela ne fera que sauver une version svg, qui ne fonctionnera pas dans IE < 11 puisque ces navigateurs ne prennent pas en charge l'élément foreignObject.

Je suppose que ce que vous voulez est une version de trame. Pour cela, vous pouvez dessiner votre svg sur un canevas en utilisant la méthode drawImage, puis appeler l'une des méthodes d'exportation du canevas (toDataURL() ou toBlob()).

Mais cela va entacher la toile dans Safari 9, car ils ont un problème de sécurité avec foreignObject et sur IE < Edge qui avait un problème de sécurité avec svg en général. L'altération de la toile rendra ses méthodes d'exportation indisponibles, et l'ensemble de l'opération sera un échec.

En outre, même dans les navigateurs qui prennent en charge, il y a une autre grande limitation:

  • Vos éléments dans la version dataURI sont hors de votre document, et ne sont pas en mesure de demander toute autre ressource externe (CSS, polices, images ...) ce qui signifie que vous devrez l'ajouter (ou une version codée dataURI pour les deux formes) dans le balisage svg avant de le transformer en dataURI.

Peut-être moins important mais le style par défaut de certains navigateurs disparaîtra sur certains éléments (principalement les entrées).

Donc dans votre cas, je m'abstiendrais d'utiliser ce hack.
La seule façon acceptable d'obtenir une version raster de vos éléments HTML consiste à les dessiner à l'aide des méthodes de dessin de canevas, tout comme le font html2canvas et d'autres bibliothèques.
Donc, je voudrais essayer de résoudre le problème actuel qui ne semble pas normal. Si vous n'avez pas besoin d'une version raster, le plus simple est de simplement enregistrer le balisage HTML dans votre db, puis de l'ajouter dans votre document (assurez-vous de le nettoyer).