如何使用 OmniFaces 在 JSF 应用程序中正确嵌入 SVG 图形

How to embed SVG graphics properly in JSF application using OmniFaces

这是

的后续

在那个问题中,我了解到 OmniFaces-2.1 快照支持通过它的 o:graphicImage 标签利用 InputStream/byte[]。

Getting started with SVG graphics objects in JSF 2.0 pages 中,我了解到标准的 graphicImage 标签只是呈现一个 img 标签,而 SVG 应该呈现为 object 标签如下:<object type="image/svg+xml" data="#{bean.svgUrl}">.

我的问题实际上直接针对 OmniFaces 项目的 BalusC:

不应该o:graphicImage以这种方式呈现 SVG 吗?我得到的只是 img-tags,它们在 IE10+ 中不起作用。

更新 #2:这是一个缩放问题!我将高度设置为 125 并开始看到图形的边缘。

更新 #1:呈现的 img 标签示例:

这个仅基于静态 SVG 文件:<img height="25" alt="" src="/javax.faces.resource/images/Logo.svg.xhtml;jsessionid=cc0acf6def65ac5c127d09384977?ln=default">

这是基于一个字节数组: <img src="data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+CjwhLS0gQ3JlYXRlZCB3aXRoIElua3NjYXBlIChodHRwOi8vd3d3Lmlua3NjYXBlLm9yZy8pIC0tPgoKPHN2ZwogICB4bWxuczpkYz0iaHR0cDovL3B1cmwub3JnL2RjL2VsZW1lbnRzLzEuMS8iCiAgIHhtbG5zOmNjPSJodHRwOi8vY3JlYXRpdmVjb21tb25zLm9yZy9ucyMiCiAgIHhtbG5zOnJkZj0iaHR0cDovL3d3dy53My5vcmcvMTk5OS8wMi8yMi1yZGYtc3ludGF4LW5zIyIKICAgeG1sbnM6c3ZnPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIKICAgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIgogICB4bWxuczppbmtzY2FwZT0iaHR0cDovL3d3dy5pbmtzY2FwZS5vcmcvbmFtZXNwYWNlcy9pbmtzY2FwZSIKICAgdmVyc2lvbj0iMS4xIgogICB3aWR0aD0iMzE5LjEzNzUxIgogICBoZWlnaHQ9IjI3OS40NjI0OSIKICAgaWQ9InN2ZzIiCiAgIHhtbDpzcGFjZT0icHJlc2VydmUiPjxtZXRhZGF0YQogICAgIGlkPSJtZXRhZGF0YTgiPjxyZGY6UkRGPjxjYzpXb3JrCiAgICAgICAgIHJkZjphYm91dD0iIj48ZGM6Zm9ybWF0PmltYWdlL3N2Zyt4bWw8L2RjOmZvcm1hdD48ZGM6dHlwZQogICAgICAgICAgIHJkZjpyZXNvdXJjZT0iaHR0cDovL3B1cmwub3JnL2RjL2RjbWl0eXBlL1N0aWxsSW1hZ2UiIC8+PC9jYzpXb3JrPjwvcmRmOlJERj48L21ldGFkYXRhPjxkZWZzCiAgICAgaWQ9ImRlZnM2IiAvPjxnCiAgICAgdHJhbnNmb3JtPSJtYXRyaXgoMS4yNSwwLDAsLTEuMjUsMCwyNzkuNDYyNSkiCiAgICAgaWQ9ImcxMCI+PGcKICAgICAgIHRyYW5zZm9ybT0ic2NhbGUoMC4xLDAuMSkiCiAgICAgICBpZD0iZzEyIj48cGF0aAogICAgICAgICBkPSJNIDEzNTMuOTYsMjE4OS44OCAyNTM5Ljc5LDEzNSBjIDguNjUsLTEzLjY5MSAxMi4yNCwtMjguODAxIDEyLjI0LC00NC42NDA2IDAsLTQ4Ljk2MSAtMzkuNiwtODkuMjgxMjcgLTg5LjI4LC04OS4yODEyNyBsIC0yMzcyLjM5ODQsMCBjIC00OC45NjEsMCAtODkuMjc3MzgsNDAuMzIwMjcgLTg5LjI3NzM4LDg5LjI4MTI3IDAsMTUuODM5NiA0LjMyMDMxLDMxLjY3OTYgMTIuMjQyMTgsNDUuMzUxNiBMIDExOTkuMTYsMjE4OS44OCBjIDM0LjU2LDU5Ljc2IDEyMC4yMyw1OS43NiAxNTUuNTEsLTAuNzIgbCAtMC43MSwwLjcyIgogICAgICAgICBpbmtzY2FwZTpjb25uZWN0b3ItY3VydmF0dXJlPSIwIgogICAgICAgICBpZD0icGF0aDE0IgogICAgICAgICBzdHlsZT0iZmlsbDojZjE0ODI0O2ZpbGwtb3BhY2l0eToxO2ZpbGwtcnVsZTpub256ZXJvO3N0cm9rZTpub25lIiAvPjxwYXRoCiAgICAgICAgIGQ9Ik0gMTM1My45NiwyMTg5Ljg4IDI1MzkuNzksMTM1IGMgOC42NSwtMTMuNjkxIDEyLjI0LC0yOC44MDEgMTIuMjQsLTQ0LjY0MDYgMCwtNDguOTYxIC0zOS42LC04OS4yODEyNyAtODkuMjgsLTg5LjI4MTI3IGwgLTIzNzIuMzk4NCwwIGMgLTQ4Ljk2MSwwIC04OS4yNzczOCw0MC4zMjAyNyAtODkuMjc3MzgsODkuMjgxMjcgMCwxNS44Mzk2IDQuMzIwMzEsMzEuNjc5NiAxMi4yNDIxOCw0NS4zNTE2IEwgMTE5OS4xNiwyMTg5Ljg4IGMgMzQuNTYsNTkuNzYgMTIwLjIzLDU5Ljc2IDE1NS41MSwtMC43MiBsIC0wLjcxLDAuNzIgeiIKICAgICAgICAgaW5rc2NhcGU6Y29ubmVjdG9yLWN1cnZhdHVyZT0iMCIKICAgICAgICAgaWQ9InBhdGgxNiIKICAgICAgICAgc3R5bGU9ImZpbGw6bm9uZTtzdHJva2U6I2YxNDgyNDtzdHJva2Utd2lkdGg6Mi4xNTAwMDAxO3N0cm9rZS1saW5lY2FwOmJ1dHQ7c3Ryb2tlLWxpbmVqb2luOm1pdGVyO3N0cm9rZS1taXRlcmxpbWl0OjQ7c3Ryb2tlLW9wYWNpdHk6MTtzdHJva2UtZGFzaGFycmF5Om5vbmUiIC8+PHBhdGgKICAgICAgICAgZD0ibSAxMjc2LjkxLDE3ODcuNCA4NzYuMjQsLTE1MTcuNzU5IC0xNzUzLjE4NSwwIDg3Ni45NDUsMTUxNy43NTkiCiAgICAgICAgIGlua3NjYXBlOmNvbm5lY3Rvci1jdXJ2YXR1cmU9IjAiCiAgICAgICAgIGlkPSJwYXRoMTgiCiAgICAgICAgIHN0eWxlPSJmaWxsOiNmZmZmZmY7ZmlsbC1vcGFjaXR5OjE7ZmlsbC1ydWxlOm5vbnplcm87c3Ryb2tlOm5vbmUiIC8+PHBhdGgKICAgICAgICAgZD0ibSAxMjc2LjkxLDE3ODcuNCA4NzYuMjQsLTE1MTcuNzU5IC0xNzUzLjE4NSwwIDg3Ni45NDUsMTUxNy43NTkgeiIKICAgICAgICAgaW5rc2NhcGU6Y29ubmVjdG9yLWN1cnZhdHVyZT0iMCIKICAgICAgICAgaWQ9InBhdGgyMCIKICAgICAgICAgc3R5bGU9ImZpbGw6bm9uZTtzdHJva2U6I2ZmZmZmZjtzdHJva2Utd2lkdGg6Mi4xNTAwMDAxO3N0cm9rZS1saW5lY2FwOmJ1dHQ7c3Ryb2tlLWxpbmVqb2luOm1pdGVyO3N0cm9rZS1taXRlcmxpbWl0OjQ7c3Ryb2tlLW9wYWNpdHk6MTtzdHJva2UtZGFzaGFycmF5Om5vbmUiIC8+PHBhdGgKICAgICAgICAgZD0ibSAxNTQyLjU5LDEyMDcuNzkgLTI1NC44OCw2OS4xMiBjIC0wLjcyLDAgLTAuNzIsMCAtMS40NCwwIC0zLjU5LDAgLTYuNDgsLTIuODcgLTYuNDgsLTYuNDcgMCwtMS40NCAwLC0yLjE2IDAuNzIsLTIuODkgbCAzNy40NCwtNjQuMDYgLTE5MS41MSwtNzAuNTcgQyA5ODAuMjczLDEwNzkuNjQgODgzLjA3NCw5MzkuOTYxIDg4My4wNzQsNzg0LjQ0MSBsIDAsLTQzNC44ODIgMTYwLjU1NiwwIDAsNDM1LjYxMyBjIDAsODcuMTA5IDU0LjcyLDE2NS41OSAxMzYuOCwxOTUuODI4IGwgMTkyLjk2LDcxLjI4IDEyLjk2LC03Mi43MjEgYyAwLjczLC0yLjg3OSAzLjYxLC01LjAzOSA2LjQ4LC01LjAzOSAyLjE3LDAgMy42MSwwLjcxOCA1LjA1LDIuODcxIGwgMTQ5Ljc1LDIxNi43MjkgYyAwLjcyLDEuNDQgMS40NCwzLjYgMS40NCw1LjA0IDAsNC4zMyAtMi44OCw3LjkyIC02LjQ4LDguNjMiCiAgICAgICAgIGlua3NjYXBlOmNvbm5lY3Rvci1jdXJ2YXR1cmU9IjAiCiAgICAgICAgIGlkPSJwYXRoMjIiCiAgICAgICAgIHN0eWxlPSJmaWxsOiMyMzFmMjA7ZmlsbC1vcGFjaXR5OjE7ZmlsbC1ydWxlOm5vbnplcm87c3Ryb2tlOm5vbmUiIC8+PHBhdGgKICAgICAgICAgZD0ibSAxNTQyLjU5LDEyMDcuNzkgLTI1NC44OCw2OS4xMiBjIC0wLjcyLDAgLTAuNzIsMCAtMS40NCwwIC0zLjU5LDAgLTYuNDgsLTIuODcgLTYuNDgsLTYuNDcgMCwtMS40NCAwLC0yLjE2IDAuNzIsLTIuODkgbCAzNy40NCwtNjQuMDYgLTE5MS41MSwtNzAuNTcgQyA5ODAuMjczLDEwNzkuNjQgODgzLjA3NCw5MzkuOTYxIDg4My4wNzQsNzg0LjQ0MSBsIDAsLTQzNC44ODIgMTYwLjU1NiwwIDAsNDM1LjYxMyBjIDAsODcuMTA5IDU0LjcyLDE2NS41OSAxMzYuOCwxOTUuODI4IGwgMTkyLjk2LDcxLjI4IDEyLjk2LC03Mi43MjEgYyAwLjczLC0yLjg3OSAzLjYxLC01LjAzOSA2LjQ4LC01LjAzOSAyLjE3LDAgMy42MSwwLjcxOCA1LjA1LDIuODcxIGwgMTQ5Ljc1LDIxNi43MjkgYyAwLjcyLDEuNDQgMS40NCwzLjYgMS40NCw1LjA0IDAsNC4zMyAtMi44OCw3LjkyIC02LjQ4LDguNjMgeiIKICAgICAgICAgaW5rc2NhcGU6Y29ubmVjdG9yLWN1cnZhdHVyZT0iMCIKICAgICAgICAgaWQ9InBhdGgyNCIKICAgICAgICAgc3R5bGU9ImZpbGw6bm9uZTtzdHJva2U6IzIzMWYyMDtzdHJva2Utd2lkdGg6Mi4xNTAwMDAxO3N0cm9rZS1saW5lY2FwOmJ1dHQ7c3Ryb2tlLWxpbmVqb2luOm1pdGVyO3N0cm9rZS1taXRlcmxpbWl0OjQ7c3Ryb2tlLW9wYWNpdHk6MTtzdHJva2UtZGFzaGFycmF5Om5vbmUiIC8+PC9nPjwvZz48L3N2Zz4=" alt="100.1 - Farlig sving" title="100.1 - Farlig sving" width="40" style="margin-left: 3px; pointer-events: none;" height="40">

因为我发现这是一个 SVG 缩放问题,而且我似乎不是唯一遇到过这个问题的人,所以我将 post 我的解决方案放在这里。

简而言之,我

  • 检索 SVG。
  • 使用 JDOM 解析它。
  • 根据指定尺寸,如果缺少视图框,则注入视图框

这是没有错误处理的 Java 代码:

    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    InputStream is = execute(builder.buildGet(), InputStream.class);
    Document doc = new SAXBuilder().build(is);
    Element root = doc.getRootElement();
    if (root.getAttribute("viewBox") == null)
    {
            String width = root.getAttributeValue("width"), height =  root.getAttributeValue("height");
            root.setAttribute("viewBox", String.format("0 0 %s %s", width, height));
    }

    new XMLOutputter().output(doc, baos);
    return baos.toByteArray();