Javascript 将内联 SVG 转换为 Base64 字符串

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/28450471/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 01:48:32  来源:igfitidea点击:

Convert inline SVG to Base64 string

javascriptsvg

提问by Niko Lang

I want to send an inline SVG image to a PHP script to Convert it to PNG with Imagick. For that I have to know how to get a base64 String out on an inline SVG. For canvas objects its a simple ".toDataURL()" but that doesn't work with inline SVGs, because its not a global function of elements.

我想将内联 SVG 图像发送到 PHP 脚本,以使用 Imagick 将其转换为 PNG。为此,我必须知道如何在内联 SVG 上获取 base64 字符串。对于画布对象,它是一个简单的“.toDataURL()”,但这不适用于内联 SVG,因为它不是元素的全局函数。

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

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

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

But how to do it for inline SVGs?

但是如何为内联 SVG 做到这一点?

回答by Robert Longson

Use XMLSerializerto convert the DOM to a string

使用XMLSerializer将 DOM 转换为字符串

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

and then btoacan convert that to base64

然后btoa可以将其转换为 base64

var encodedData = window.btoa(s);

Just prepend the data URL intro i.e. data:image/svg+xml;base64,and there you have it.

只需添加数据 URL 介绍,即data:image/svg+xml;base64,,您就拥有了它。

回答by John Haugeland

You can do it relatively straightforwardly as follows. The short version is

您可以按如下方式相对简单地完成此操作。简短的版本是

  1. Make an image not attached to the dom
  2. Set its size to match the source svg
  3. base64encode the source svg, append the relevant data, set img src
  4. Get the canvascontext; .drawImagethe 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>
    

  1. 制作一个不附加到 dom 的图像
  2. 设置其大小以匹配源 svg
  3. base64编码源svg,附加相关数据,设置img src
  4. 获取canvas上下文;.drawImage图片

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

JSFiddle: https://jsfiddle.net/oz3tjnk7/

JSFiddle:https://jsfiddle.net/oz3tjnk7/

回答by Humoyun Ahmad

I had the same problem while working on SVG based Floorplan Editor, after drawing a floorplan we have to save it for later use. Long story, code is better than talking, Here is the final code which worked for me:

我在使用基于 SVG 的平面图编辑器时遇到了同样的问题,在绘制平面图后,我们必须保存它以备后用。长话短说,代码比说话好,这是对我有用的最终代码:

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);  
}

回答by Anh Hoang

I just try to collect and explain all great ideas on this issue. This works on both Chrome 76 and Firefox 68

我只是试图收集和解释关于这个问题的所有伟大的想法。这适用于 Chrome 76 和 Firefox 68

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

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

// Serialize the 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);

回答by collapsar

This line will perform the conversion:

此行将执行转换:

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

Make sure that the proper charset/encoding has been selected!

确保选择了正确的字符集/编码!