我想将内联SVG图像发送到PHP脚本,以使用Imagick将其转换为PNG。为此,我必须知道如何在内联SVG上获取base64字符串。对于canvas对象,它是一个简单的“.toDataURL()”但不适用于内联SVG,因为它不是元素的全局函数。
test = function(){
var b64 = document.getElementById("svg").toDataURL();
alert(b64);
}
http://jsfiddle.net/nikolang/ccx195qj/1/
但如何为内联SVG做到这一点?
答案 0 :(得分:50)
使用XMLSerializer将DOM转换为字符串
var s = new XMLSerializer().serializeToString(document.getElementById("svg"))
然后btoa可以将其转换为base64
var encodedData = window.btoa(s);
只需在数据网址前面加上data:image/svg+xml;base64,
,然后就可以了。
答案 1 :(得分:3)
你可以按照以下相对简单的方式做到这一点。简短版本是
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>
答案 2 :(得分:2)
在使用基于SVG的Floorplan编辑器时,我遇到了同样的问题,绘制完平面图后,我们必须将其保存以备后用。长话短说,代码总比谈论好。这是对我有用的最终代码:
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);
}
答案 3 :(得分:1)
我只是尝试收集并解释有关此问题的所有好主意。这在Chrome 76和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);
答案 4 :(得分:0)
此行将执行转换:
window.btoa($("svg").wrap("<div id='xyz'/>").parent().html());
确保选择了正确的字符集/编码!