【问题标题】:Clip Path Lost while super-imposing SVG images叠加 SVG 图像时剪辑路径丢失
【发布时间】:2016-02-12 21:17:21
【问题描述】:

我按照How do I superimpose one SVG image onto another using Apache Batik? 的说明(以及来自其他来源的一些额外细节)进行操作

直到现在,大部分时间都运行良好。但是,现在,我的每个 svg 文档(图像)都有剪辑路径。当我放置 2 个或更多图像时,只有第二个路径保存在输出中。我丢失了所有其他剪辑路径。我需要做些什么来保留每个图像的剪辑路径吗?我查看了 SVG 输出,只看到一个剪辑路径。我的代码如下所示:

public void PlaceSVGImage(SVGDocument a, Point C)
{       
    String xatt = String.format("%f", C.X);
    String yatt = String.format("%f", C.Y);

    org.w3c.dom.Node ae = SVGC.SVGD.importNode(a.getDocumentElement(), true);

    ((Element) ae).removeAttribute("viewBox");
    ((Element) ae).setAttribute("x", xatt);
    ((Element) ae).setAttribute("y", yatt);

    if (FIRSTCHILD)
    {
        SVGC.SVGD.getDocumentElement().appendChild(ae);
        FIRSTCHILD = false;
        NullNode = ae;
    }
    else
    {
        SVGC.SVGD.getDocumentElement().insertBefore(ae, NullNode);
    }
}

然后我使用一些标准代码来显示 SVGC.SVGD。

任何见解将不胜感激。

【问题讨论】:

    标签: java svg batik clip-path


    【解决方案1】:

    根据收到的cmets,我们解决了如下问题: (a) 将 Batik 生成的 svg 文档转换为字符串;然后,(b)使用简单的字符串替换将剪辑路径名称的默认分配(Batik 将它们命名为 clippath1、clippath2 等)更改为唯一的名称。然后,当这些 svg 文档放在一个(更大的)svg 文档中时,剪辑路径名称将全部不同,这个问题就解决了。对于那些可能从我们的代码中受益的人,请参见下文。如果有更好的方法,请告诉我们。

    public static SVGDocument clipReplacer(SVGDocument SVGD, String S_OLD, String S_NEW)
    {
        String SVGString = SVGLib.getString(SVGD);
        SVGDocument doc = null;
        SVGString = SVGString.replaceAll(S_OLD, S_NEW);
        StringReader reader = new StringReader(SVGString);
    
        //System.out.println(SVGString);
    
        try
        {
            String parser = XMLResourceDescriptor.getXMLParserClassName();
            SAXSVGDocumentFactory f = new SAXSVGDocumentFactory(parser);
            doc = f.createSVGDocument("http://www.w3.org/2000/svg", reader);
        }
        catch (Exception ex)
        {
        }
        finally
        {
            reader.close();
        }
    
        return doc;
    }
    
    public static String getString(SVGDocument SVGD)
    {
        /*
         * Converts a given SVGDocument to String
         */
    
        Writer stringWriter = new StringWriter();
        TranscoderInput input = new TranscoderInput(SVGD);
        TranscoderOutput output = new TranscoderOutput(stringWriter);
    
        SVGTranscoder X = new SVGTranscoder();
        try
        {
            X.addTranscodingHint(SVGTranscoder.KEY_FORMAT,
                    SVGTranscoder.VALUE_FORMAT_ON);
            output.setOutputStream(System.out);
            X.transcode(input, output);
        }
        catch (TranscoderException e)
        {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    
        return stringWriter.toString();
    }
    

    【讨论】:

      【解决方案2】:

      剪辑路径元素由其id 属性引用。

      <clipPath id="clipPath1">
          ...
      </clipPAth>
      

      所以检查你的 SVG 没有重复的 clipPath id 属性。如果您的 SVG 文件是使用 SVG 编辑器(例如 Illustrator)制作的,那么它们具有相同 ID 的剪辑路径元素的可能性非常高。

      显然,SVG 中的所有 id 都必须是唯一的。否则渲染器将不知道它应该使用哪个同名的&lt;clipPaths&gt;

      【讨论】:

      • 感谢您的回答。你说的对。首先,当您查看 svg Batik 转码器产生的结果时,在外部 组内,有两个 组对应于每个图像。我想知道这是否可以。其次,每个内部 组都有一个名为 clipPath1 的剪辑路径。我希望这些都是本地的(因此没有冲突)。正如您所说,它们不是本地的,而是全球的。 Batik 中有没有办法实际命名剪辑路径,以便我可以使它们独一无二(我可以生成唯一的名称)?我目前使用一个简单的 g.setClip(generalPath P) 来设置剪辑。
      • &lt;svg&gt; 元素可以在其中嵌套&lt;svg&gt;。它可能不常见,但在某些情况下很有用。 id 属性值必须在文档中是唯一的。我没有使用 Batik,但我希望您需要通过 DOM 方法手动添加 &lt;clipPath&gt; 元素。设置它的id。然后引用它。
      猜你喜欢
      • 2021-05-01
      • 1970-01-01
      • 2021-09-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-09-25
      • 2016-10-19
      • 1970-01-01
      相关资源
      最近更新 更多