剪辑路径在超级强制SVG图像时丢失

时间:2016-02-01 23:01:51

标签: java svg batik clip-path

我按照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。

任何见解都将受到赞赏。

2 个答案:

答案 0 :(得分:0)

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

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

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

显然,SVG中的所有ID必须是唯一的。否则,渲染器将不知道它应该使用哪个名称相同的<clipPaths>

答案 1 :(得分:0)

根据收到的意见,我们能够解决以下问题:(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();
}