首页 > 解决方案 > Apache Batik 无法在 Swing 应用程序中显示 SVG

问题描述

我下面的代码是从官方指南中提取的。该代码将毫无问题地呈现一些 SVG 文件,但其他会导致异常java.awt.image.ImagingOpException: Unable to transform src image。我创建了一个“工作图像”和一个“问题图像”作为小例子。

请注意,我无法将 SVG 文件直接添加到 StackOverflow 问题中,它们不是受支持的文件类型,因此这里是一个工作图像和一个问题图像的链接。以下也是原始文件内容。

我发现了多个潜在的重复问题,但没有一个有答案。我可以在我自己的程序中解决这个问题而不修补蜡染吗?是否有其他推荐的方式在 Java 中显示 SVG?AFAIK,蜡染是参考实现。是什么导致一个 SVG 失败而另一个(几乎相同)的工作正常?我怎样才能避免这个问题,而不必扫描/编辑我的用户可能选择加载的每个 SVG 以避免一些边缘情况错误?

public class SVGApplication {

    public static void main(String[] args) {
        // Create a new JFrame.
        JFrame f = new JFrame("Batik");
        SVGApplication app = new SVGApplication();
        app.frame = f;

        f.getContentPane().add(app.createComponents());
        f.addWindowListener(new WindowAdapter() {
            public void windowClosing(WindowEvent e) {
                System.exit(0);
            }
        });
        f.setSize(400, 400);
        f.setVisible(true);
    }

    JFrame frame;
    JButton button = new JButton("Load...");
    JLabel label = new JLabel();
    JSVGCanvas svgCanvas = new JSVGCanvas();

    public JComponent createComponents() {
        final JPanel panel = new JPanel(new BorderLayout());
        JPanel p = new JPanel(new FlowLayout(FlowLayout.LEFT));
        p.add(button);
        p.add(label);
        panel.add("North", p);
        panel.add("Center", svgCanvas);

        // Set the button action.
        button.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent ae) {
                JFileChooser fc = new JFileChooser(".");
                int choice = fc.showOpenDialog(panel);
                if (choice == JFileChooser.APPROVE_OPTION) {
                    File f = fc.getSelectedFile();
                    try {
                        svgCanvas.setURI(f.toURL().toString());
                    } catch (IOException ex) {
                        ex.printStackTrace();
                    }
                }
            }
        });

        return panel;
    }
}

对于所有图像,程序最初会很好地加载图像,但是当您缩放 JFrame 时,它​​开始在“问题”图像上喷出异常,例如

java.awt.image.ImagingOpException: Unable to transform src image
    at java.awt.image.AffineTransformOp.filter(AffineTransformOp.java:358)
    at org.apache.batik.ext.awt.image.rendered.AffineRed.genRect(AffineRed.java:193)
    at org.apache.batik.ext.awt.image.rendered.AffineRed.copyData(AffineRed.java:109)
    at org.apache.batik.ext.awt.image.rendered.PadRed.copyData(PadRed.java:88)
    at org.apache.batik.ext.awt.image.rendered.ColorMatrixRed.copyData(ColorMatrixRed.java:116)
    at org.apache.batik.ext.awt.image.rendered.PadRed.copyData(PadRed.java:88)
    at org.apache.batik.ext.awt.image.rendered.PadRed.copyData(PadRed.java:88)
    at org.apache.batik.ext.awt.image.rendered.PadRed.copyData(PadRed.java:88)
    at org.apache.batik.ext.awt.image.rendered.CompositeRed.genRect(CompositeRed.java:179)
    at org.apache.batik.ext.awt.image.rendered.CompositeRed.copyData(CompositeRed.java:139)
    at org.apache.batik.ext.awt.image.rendered.Any2sRGBRed.copyData(Any2sRGBRed.java:166)
    at org.apache.batik.ext.awt.image.rendered.FormatRed.copyData(FormatRed.java:116)
    at org.apache.batik.ext.awt.image.GraphicsUtil.drawImage(GraphicsUtil.java:347)
    at org.apache.batik.ext.awt.image.GraphicsUtil.drawImage(GraphicsUtil.java:455)
    at org.apache.batik.ext.awt.image.renderable.PadRable8Bit.paintRable(PadRable8Bit.java:135)
    at org.apache.batik.ext.awt.image.GraphicsUtil.drawImage(GraphicsUtil.java:440)
    at org.apache.batik.ext.awt.image.renderable.PadRable8Bit.paintRable(PadRable8Bit.java:135)
    at org.apache.batik.ext.awt.image.GraphicsUtil.drawImage(GraphicsUtil.java:440)
    at org.apache.batik.ext.awt.image.renderable.FilterChainRable8Bit.paintRable(FilterChainRable8Bit.java:251)
    at org.apache.batik.ext.awt.image.GraphicsUtil.drawImage(GraphicsUtil.java:440)
    at org.apache.batik.gvt.AbstractGraphicsNode.paint(AbstractGraphicsNode.java:549)
    at org.apache.batik.gvt.ShapeNode.paint(ShapeNode.java:143)
    at org.apache.batik.gvt.CompositeGraphicsNode.primitivePaint(CompositeGraphicsNode.java:165)
    at org.apache.batik.gvt.AbstractGraphicsNode.paint(AbstractGraphicsNode.java:509)
    at org.apache.batik.gvt.CompositeGraphicsNode.primitivePaint(CompositeGraphicsNode.java:165)
    at org.apache.batik.gvt.CanvasGraphicsNode.primitivePaint(CanvasGraphicsNode.java:159)
    at org.apache.batik.gvt.AbstractGraphicsNode.paint(AbstractGraphicsNode.java:509)
    at org.apache.batik.gvt.CompositeGraphicsNode.primitivePaint(CompositeGraphicsNode.java:165)
    at org.apache.batik.gvt.AbstractGraphicsNode.paint(AbstractGraphicsNode.java:509)
    at org.apache.batik.gvt.renderer.MacRenderer.repaint(MacRenderer.java:360)
    at org.apache.batik.gvt.renderer.MacRenderer.repaint(MacRenderer.java:291)
    at org.apache.batik.swing.gvt.GVTTreeRenderer.run(GVTTreeRenderer.java:123)

类似的先前问题:这篇文章建议修补蜡染源,这不是很有吸引力。这篇文章解释了一个确实在 batik 1.7+ 中应用的修复,但是我使用的是 1.11,这不再有效

附加数据:因为 SVG 文件似乎很难托管,所以我选择在此处将“工作”与“问题”文件的原始内容作为文本包含在内。这似乎在“完整的、可验证的”问题之间取得了适当的平衡。

Working Image: <?xml version="1.0" encoding="UTF-8" standalone="no"?><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" contentScriptType="application/ecmascript" contentStyleType="text/css" height="141px" preserveAspectRatio="none" style="width:94px;height:141px;" version="1.1" viewBox="0 0 94 141" width="94px" zoomAndPan="magnify"><defs><filter height="300%" id="fdmfjjhypbn8w" width="300%" x="-1" y="-1"><feGaussianBlur result="blurOut" stdDeviation="2.0"/><feColorMatrix in="blurOut" result="blurOut2" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 .4 0"/><feOffset dx="4.0" dy="4.0" in="blurOut2" result="blurOut3"/><feBlend in="SourceGraphic" in2="blurOut3" mode="normal"/></filter></defs><g><line style="stroke: #A80036; stroke-width: 1.0; stroke-dasharray: 5.0,5.0;" x1="40" x2="40" y1="38.4883" y2="100.7988"/><rect fill="#FEFECE" filter="url(#fdmfjjhypbn8w)" height="30.4883" style="stroke: #A80036; stroke-width: 1.5;" width="60" x="8" y="3"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacingAndGlyphs" textLength="46" x="15" y="23.5352">Actor1</text><rect fill="#FEFECE" filter="url(#fdmfjjhypbn8w)" height="30.4883" style="stroke: #A80036; stroke-width: 1.5;" width="60" x="8" y="99.7988"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacingAndGlyphs" textLength="46" x="15" y="120.334">Actor1</text><line style="stroke: #A80036; stroke-width: 1.0;" x1="40" x2="82" y1="69.7988" y2="69.7988"/><line style="stroke: #A80036; stroke-width: 1.0;" x1="82" x2="82" y1="69.7988" y2="82.7988"/><line style="stroke: #A80036; stroke-width: 1.0;" x1="41" x2="82" y1="82.7988" y2="82.7988"/><polygon fill="#A80036" points="51,78.7988,41,82.7988,51,86.7988,47,82.7988" style="stroke: #A80036; stroke-width: 1.0;"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacingAndGlyphs" textLength="24" x="47" y="65.0566">test</text><!--@startuml\nActor1 -> Actor1: test\n@enduml--></g></svg>
Problem Image: <?xml version="1.0" encoding="UTF-8" standalone="no"?><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" contentScriptType="application/ecmascript" contentStyleType="text/css" height="183px" preserveAspectRatio="none" style="width:168px;height:183px;" version="1.1" viewBox="0 0 168 183" width="168px" zoomAndPan="magnify"><defs><filter height="300%" id="fc9m2fo3xvklq" width="300%" x="-1" y="-1"><feGaussianBlur result="blurOut" stdDeviation="2.0"/><feColorMatrix in="blurOut" result="blurOut2" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 .4 0"/><feOffset dx="4.0" dy="4.0" in="blurOut2" result="blurOut3"/><feBlend in="SourceGraphic" in2="blurOut3" mode="normal"/></filter></defs><g><line style="stroke: #A80036; stroke-width: 1.0; stroke-dasharray: 5.0,5.0;" x1="40" x2="40" y1="38.4883" y2="143.1094"/><line style="stroke: #A80036; stroke-width: 1.0; stroke-dasharray: 5.0,5.0;" x1="114" x2="114" y1="38.4883" y2="143.1094"/><rect fill="#FEFECE" filter="url(#fc9m2fo3xvklq)" height="30.4883" style="stroke: #A80036; stroke-width: 1.5;" width="60" x="8" y="3"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacingAndGlyphs" textLength="46" x="15" y="23.5352">Actor1</text><rect fill="#FEFECE" filter="url(#fc9m2fo3xvklq)" height="30.4883" style="stroke: #A80036; stroke-width: 1.5;" width="60" x="8" y="142.1094"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacingAndGlyphs" textLength="46" x="15" y="162.6445">Actor1</text><rect fill="#FEFECE" filter="url(#fc9m2fo3xvklq)" height="30.4883" style="stroke: #A80036; stroke-width: 1.5;" width="60" x="82" y="3"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacingAndGlyphs" textLength="46" x="89" y="23.5352">Actor2</text><rect fill="#FEFECE" filter="url(#fc9m2fo3xvklq)" height="30.4883" style="stroke: #A80036; stroke-width: 1.5;" width="60" x="82" y="142.1094"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacingAndGlyphs" textLength="46" x="89" y="162.6445">Actor2</text><line style="stroke: #A80036; stroke-width: 1.0;" x1="40" x2="82" y1="69.7988" y2="69.7988"/><line style="stroke: #A80036; stroke-width: 1.0;" x1="82" x2="82" y1="69.7988" y2="82.7988"/><line style="stroke: #A80036; stroke-width: 1.0;" x1="41" x2="82" y1="82.7988" y2="82.7988"/><polygon fill="#A80036" points="51,78.7988,41,82.7988,51,86.7988,47,82.7988" style="stroke: #A80036; stroke-width: 1.0;"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacingAndGlyphs" textLength="24" x="47" y="65.0566">test</text><line style="stroke: #A80036; stroke-width: 1.0;" x1="114" x2="156" y1="112.1094" y2="112.1094"/><line style="stroke: #A80036; stroke-width: 1.0;" x1="156" x2="156" y1="112.1094" y2="125.1094"/><line style="stroke: #A80036; stroke-width: 1.0;" x1="115" x2="156" y1="125.1094" y2="125.1094"/><polygon fill="#A80036" points="125,121.1094,115,125.1094,125,129.1094,121,125.1094" style="stroke: #A80036; stroke-width: 1.0;"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacingAndGlyphs" textLength="24" x="121" y="107.3672">test</text><!--\n@startuml\nActor1 -> Actor1: test\nActor2 -> Actor2: test\n@enduml\n--></g></svg>

标签: javasvgbatik

解决方案


推荐阅读