web-dev-qa-db-fra.com

Convertir SVG en ligne en chaîne Base64

Je veux envoyer une image SVG en ligne vers un script PHP pour la convertir en PNG avec Imagick. Pour cela, je dois savoir comment obtenir une chaîne base64 sur un SVG en ligne. Pour les objets de canevas c'est un simple ".toDataURL ()" mais cela ne fonctionne pas avec les SVG en ligne, car ce n'est pas une fonction globale des éléments.

test = function(){
    var b64 = document.getElementById("svg").toDataURL();
    alert(b64);
}

http://jsfiddle.net/nikolang/ccx195qj/1/

Mais comment faire pour les SVG en ligne?

26
Niko Lang

Utilisez XMLSerializer pour convertir le DOM en chaîne

var s = new XMLSerializer().serializeToString(document.getElementById("svg"))

puis btoa peut convertir cela en base64

var encodedData = window.btoa(s);

Ajoutez simplement l'intro de l'URL de données, c'est-à-dire data:image/svg+xml;base64, Et voila.

54
Robert Longson

Vous pouvez le faire de manière relativement simple comme suit. La version courte est

  1. Faire une image non attachée au dom
  2. Définissez sa taille pour qu'elle corresponde à la source svg
  3. base64 encoder la source svg, ajouter les données pertinentes, définir img src
  4. Obtenez le contexte canvas; .drawImage l'image

    <script type="text/javascript">
    
    
        window.onload = function() {
            paintSvgToCanvas(document.getElementById('source'), document.getElementById('tgt'));
        }
    
    
    
        function paintSvgToCanvas(uSvg, uCanvas) {
    
            var pbx = document.createElement('img');
    
            pbx.style.width  = uSvg.style.width;
            pbx.style.height = uSvg.style.height;
    
            pbx.src = 'data:image/svg+xml;base64,' + window.btoa(uSvg.outerHTML);
            uCanvas.getContext('2d').drawImage(pbx, 0, 0);
    
        }
    
    
    </script>
    
    <svg xmlns="http://www.w3.org/2000/svg" width="467" height="462" id="source">
      <rect x="80" y="60" width="250" height="250" rx="20" style="fill:#ff0000; stroke:#000000;stroke-width:2px;" />
      <rect x="140" y="120" width="250" height="250" rx="40" style="fill:#0000ff; stroke:#000000; stroke-width:2px; fill-opacity:0.7;" />
    </svg>
    
    <canvas height="462px" width="467px" id="tgt"></canvas>
    
3
John Haugeland

J'ai eu le même problème en travaillant sur l'éditeur de plan d'étage basé sur SVG, après avoir dessiné un plan d'étage, nous devons le sauvegarder pour une utilisation ultérieure. Longue histoire, le code vaut mieux que de parler, voici le code final qui a fonctionné pour moi:

async saveFloorplan() {
  const svgElem = document.querySelector('#svg-element');
  let xmlSource = new XMLSerializer().serializeToString(svgElem);

  if (!xmlSource.match(/^<svg[^>]+xmlns="http:\/\/www\.w3\.org\/2000\/svg"/)) {
    xmlSource = xmlSource.replace(/^<svg/, '<svg xmlns="http://www.w3.org/2000/svg"');
  }
  if (!xmlSource.match(/^<svg[^>]+"http:\/\/www\.w3\.org\/1999\/xlink"/)) {
    xmlSource = xmlSource.replace(/^<svg/, '<svg xmlns:xlink="http://www.w3.org/1999/xlink"');
  }
  // add xml declaration
  xmlSource = `<?xml version="1.0" standalone="no"?>\r\n${xmlSource}`;

  const svg64 = encodeURIComponent(xmlSource);
  const b64Start = 'data:image/svg+xml;charset=utf-8,';

  const imgEl = new Image();
  const image64 = b64Start + svg64;
  imgEl.src = image64;

  const blobResp = await fetch(imgEl.src);
  const blob = await blobResp.blob();

  const payload = {...}

  payload.fileExtension = 'svg';
  payload.fileSize = blob.size;

  const formData = new FormData();
  formData.append('file', blob);

  const uploaded = await api.uploadFile(formData);  
}
2
Humoyun Ahmad

Cette ligne effectuera la conversion:

window.btoa($("svg").wrap("<div id='xyz'/>").parent().html());

Assurez-vous que le bon jeu de caractères/encodage a été sélectionné!

0
collapsar

J'essaie simplement de rassembler et d'expliquer toutes les bonnes idées sur cette question. Cela fonctionne sur les deux Chrome 76 et Firefox 68

var svgElement = document.getElementById('svgId');

// Create your own image
var img = document.createElement('img');

// Serialize svg to string
var svgString = new XMLSerializer().serializeToString(svgElement);

// Remove any characters outside the Latin1 range
var decoded = unescape(encodeURIComponent(svgString));

// Now we can use btoa to convert the svg to base64
var base64 = btoa(decoded);

var imgSource = `data:image/svg+xml;base64,${base64}`;

img.setAttribute('src', imgSource);
0
Anh Hoang