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
Convert inline SVG to Base64 string
提问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
您可以按如下方式相对简单地完成此操作。简短的版本是
- Make an image not attached to the dom
- Set its size to match the source
svg base64encode the sourcesvg, append the relevant data, setimg srcGet 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>
- 制作一个不附加到 dom 的图像
- 设置其大小以匹配源
svg base64编码源svg,附加相关数据,设置img src获取
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!
确保选择了正确的字符集/编码!

