当我拥有的是图像的base64字符串时,如何使用<svg>标签?

时间:2016-09-19 22:06:39

标签: html svg

我想展示一个SVG图像。我想使用CSS直接修改SVG,所以我需要使用<svg>标签。但是,我没有SVG源 - 我只有SVG编码为base64字符串。在我的HTML页面中,使用图片标记,它看起来像这样:

<img alt="" src="data:image/svg+xml;base64,lotsofunreadablestuff...">

如何使用相同的base64字符串创建显示相同图像的svg标记?到目前为止,我发现的每个主题和文档似乎都假设我在SVG中使用<use xlink:href=...></use>标记或在我的<svg>标记中包含原始SVG,适用于我的情况。

我想做这样的事情:

<svg>
  <magicalSourceTag>
    data:image/svg+xml;base64,lotsofunreadablestuff...
  </magicalSourceTag>
</svg>

1 个答案:

答案 0 :(得分:5)

You can only apply CSS to SVGs within the same document。这意味着您要么必须将SVG内联到HTML中,要么将CSS嵌入到SVG代码中。

现在,为了内联SVG,它取决于你拥有的东西。

对于这个答案,我将使用以下数据网址,该网址会转换为(应该是什么)相机图标:

data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIj8+Cjxzdmcgdmlld0JveD0iMCAtMTAgMTAwIDg1IiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPgogICAgPGRlZnM+CiAgICAgICAgPGNsaXBQYXRoIGlkPSJjbGlwIj4KICAgICAgICAgICAgPHBhdGggZD0iTTAsMCBMMTAwLDAgTDEwMCw3NSBMMCw3NSBMMCwwCiAgICAgICAgICAgICAgICAgICAgIE01MCwxNSBBMjAsMjAgMCAxLDAgNTAsNjAgQTIwLDIwIDAgMSwwIDUwLDE1CiAgICAgICAgICAgICAgICAgICAgIE01MCwyNSBBMTIuNSwxMi41IDAgMSwxIDUwLDUwIEExMi41LDEyLjUgMCAxLDEgNTAsMjUiLz4KICAgICAgICA8L2NsaXBQYXRoPgogICAgPC9kZWZzPgogICAgPHJlY3QgeD0iMzAiIHk9Ii0xMCIgd2lkdGg9IjQwIiBoZWlnaHQ9IjIwIiByeD0iMTAiIHJ5PSIxMCIvPgogICAgPHJlY3QgeD0iMCIgeT0iMCIgd2lkdGg9IjEwMCIgaGVpZ2h0PSI3NSIgcng9IjE1IiByeT0iMTUiIGNsaXAtcGF0aD0idXJsKCNjbGlwKSIvPgo8L3N2Zz4K

1。静态数据

如果您有想要使用的硬编码数据URL,可以使用任何base64解码器对其进行简单解码。只需将base64,之后的blob粘贴到解码器中,它就应该返回原始XML,然后将其嵌入到HTML中。

如果您使用上面的数据网址,请查看the first Google result for "base64 decode"并将base64,之后的部分粘贴到其中,即可获得:

<?xml version="1.0"?>
<svg viewBox="0 -10 100 85" xmlns="http://www.w3.org/2000/svg">
    <defs>
        <clipPath id="clip">
            <path d="M0,0 L100,0 L100,75 L0,75 L0,0
                     M50,15 A20,20 0 1,0 50,60 A20,20 0 1,0 50,15
                     M50,25 A12.5,12.5 0 1,1 50,50 A12.5,12.5 0 1,1 50,25"/>
        </clipPath>
    </defs>
    <rect x="30" y="-10" width="40" height="20" rx="10" ry="10"/>
    <rect x="0" y="0" width="100" height="75" rx="15" ry="15" clip-path="url(#clip)"/>
</svg>

您应该在将<?xml version="1.0"?>标记内嵌到HTML之前将其删除为100%标准兼容,但这就是您需要做的全部工作,如果粘贴到您的HTML中,其余部分应该可以正常工作。

2。动态数据

如果数据URL未修复,则需要您的应用程序进行解码和内联。

再次有两种方法可以做到这一点:

2.1服务器端

我会考虑服务器端内联处理动态数据的最简洁方法 从理论上讲,任何编程语言都可以做到这一点,只要它有一个base64解码器和一个XML解析器,它就不应该太复杂。
由于您没有说出您正在使用的服务器端语言(如果有),我将使用PHP作为示例,并且我正在使用DOM扩展,该扩展已启用,默认情况下可用。

首先,您需要从数据URL中获取XML。您可以(ab)使用file_get_contents

$xml = file_get_contents($dataURL);

接下来,您将要将该XML解析为DOM文档:

$dom = new DOMDocument();
$dom->loadXML($xml);

然后你只想导出根节点(没有<?xml标签),这样它就可以内联到HTML中。您可以通过以根节点作为第一个参数调用$dom->saveXML来完成此操作,即:

$svg = $dom->saveXML($dom->documentElement);

[Online demo]

这当然有一个缺点,就是首先需要运行服务器端应用程序(除了Web服务器)。

2.2客户端

如果您需要或想要在浏览器中执行此操作,那么实际上只有一个选项:JavaScript。

与PHP的file_get_contents类似,您可以(ab)使用JavaScript的XMLHttpRequest来“加载”来自网址的数据:

var xhr = new XMLHttpRequest();
xhr.open('GET', dataURL);
xhr.addEventListener('load', function(ev)
{
    var xml = ev.target.response;
    // All following code here
});
xhr.send(null);

相当于PHP的DOM库,JavaScript有DOMParser,您可以使用它将整个字符串解析为DOM文档:

var dom = new DOMParser();
var svg = dom.parseFromString(xml, 'image/svg+xml');

最后,您可以将根元素(即svg.rootElement)附加到DOM树中的任何位置,例如。

document.body.appendChild(svg.rootElement);

演示:

var dataURL = 'data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIj8+Cjxzdmcgdmlld0JveD0iMCAtMTAgMTAwIDg1IiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPgogICAgPGRlZnM+CiAgICAgICAgPGNsaXBQYXRoIGlkPSJjbGlwIj4KICAgICAgICAgICAgPHBhdGggZD0iTTAsMCBMMTAwLDAgTDEwMCw3NSBMMCw3NSBMMCwwCiAgICAgICAgICAgICAgICAgICAgIE01MCwxNSBBMjAsMjAgMCAxLDAgNTAsNjAgQTIwLDIwIDAgMSwwIDUwLDE1CiAgICAgICAgICAgICAgICAgICAgIE01MCwyNSBBMTIuNSwxMi41IDAgMSwxIDUwLDUwIEExMi41LDEyLjUgMCAxLDEgNTAsMjUiLz4KICAgICAgICA8L2NsaXBQYXRoPgogICAgPC9kZWZzPgogICAgPHJlY3QgeD0iMzAiIHk9Ii0xMCIgd2lkdGg9IjQwIiBoZWlnaHQ9IjIwIiByeD0iMTAiIHJ5PSIxMCIvPgogICAgPHJlY3QgeD0iMCIgeT0iMCIgd2lkdGg9IjEwMCIgaGVpZ2h0PSI3NSIgcng9IjE1IiByeT0iMTUiIGNsaXAtcGF0aD0idXJsKCNjbGlwKSIvPgo8L3N2Zz4K';
var xhr = new XMLHttpRequest();
xhr.open('GET', dataURL);
xhr.addEventListener('load', function(ev)
{
    var xml = ev.target.response;
    var dom = new DOMParser();
    var svg = dom.parseFromString(xml, 'image/svg+xml');
    document.body.appendChild(svg.rootElement);
});
xhr.send(null);