简体   繁体   English

将内联 SVG 转换为 Base64 字符串

[英]Convert inline SVG to Base64 string

I want to send an inline SVG image to a PHP script to Convert it to PNG with Imagick.我想将内联 SVG 图像发送到 PHP 脚本以使用 Imagick 将其转换为 PNG。 For that I have to know how to get a base64 String out on an inline SVG.为此,我必须知道如何在内联 SVG 上获取 base64 字符串。 For canvas objects its a simple ".toDataURL()" but that doesn't work with inline SVGs, because its not a global function of elements.对于画布对象,它是一个简单的“.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 做呢?

Use XMLSerializer to convert the DOM to a string使用XMLSerializer将 DOM 转换为字符串

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

and then btoa can convert that to base64然后btoa可以将其转换为 base64

var encodedData = window.btoa(s);

Just prepend the data URL intro ie data:image/svg+xml;base64, and there you have it.只需添加数据 URL 介绍,即data:image/svg+xml;base64,就可以了。

You can do it relatively straightforwardly as follows.您可以按如下方式相对简单地完成此操作。 The short version is简短的版本是

  1. Make an image not attached to the dom制作一个不附加到 dom 的图像
  2. Set its size to match the source svg设置其大小以匹配源svg
  3. base64 encode the source svg , append the relevant data, set img src base64编码源svg ,附加相关数据,设置img src
  4. Get the canvas context;获取canvas上下文; .drawImage the image .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/

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

I had the same problem while working on SVG based Floorplan Editor, after drawing a floorplan we have to save it for later use.我在使用基于 SVG 的平面图编辑器时遇到了同样的问题,在绘制平面图后,我们必须保存它以备后用。 Long story, code is better than talking, Here is the final code which worked for me:长话短说,代码比说话好,这是对我有用的最终代码:

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

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!确保选择了正确的字符集/编码!

// 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")

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM