将内联 SVG 转换为 Base64 字符串

问题描述 投票:0回答:7

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

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

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

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

javascript svg
7个回答
124
投票

使用 XMLSerializer 将 DOM 转换为字符串

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

然后btoa可以将其转换为base64

var encodedData = window.btoa(s);

只需在前面加上数据 URL 介绍即可,即

data:image/svg+xml;base64,
就可以了。


24
投票

我只是尝试收集并解释关于这个问题的所有好主意。这适用于 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);

10
投票

您可以按照以下相对简单的方式进行操作。简短版本是

  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/


3
投票

我在使用基于 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);  
}

0
投票

如果您想使用输出作为图像的 src 属性,base64 图像的替代解决方案是使用 Blob

const svgUrl = URL.createObjectURL(new Blob([svg], { type: 'image/svg+xml' }))

输出:

<img src="blob:http://localhost:3000/49d88b00-a337-4c58-bce1-ca211634d9b6" alt="Alt text">

-1
投票

此行将执行转换:

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

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


-1
投票
// 1. get the element
let e = document.getElementById("svg");

// 2. get the string representation of the element
var s = new XMLSerializer().serializeToString(e);
// or 
var s = e.outerHTML;

// 3. convert the string to url
// convert to utf8
var url = "data:image/svg+xml;utf8," + encodeURIComponent(s);
// convert to base64
var url = "data:image/svg+xml;base64," + window.btoa(unescape(encodeURIComponent(s)));
// or
var url = "data:image/svg+xml;base64," + Buffer.from(s, "utf-8").toString("base64")
© www.soinside.com 2019 - 2024. All rights reserved.