在JPanel上绘制SVG图像

12

我想在我的Java应用程序中将可缩放、旋转、着色并带有alpha层的SVG图像绘制到JPanel上。我该如何实现这一点?可能会有多个这样的图像重叠。

我不太了解如何在Java中使用SVG图像,所以请从头开始解释,而不仅仅是渲染过程 :)

谢谢!


2
你在来这里之前有没有试过谷歌搜索呢?:https://dev59.com/-2LVa4cB1Zd3GeqPtSLh - Josh M
@JoshM 是的,我确实有过类似的经历,但我从未遇到过这样的问题。 - Jochem Kuijpers
2个回答

13

您需要将SVG图像转换为可由JPanel显示的类型--我假设您已经知道如何使用BufferedImage来显示例如PNG,并且不需要编辑SVG,只需显示它。

关键在于Java没有本地支持SVG。您必须使用类似batik的库来加载和转换图像为可显示格式。

我从http://bbgen.net/blog/2011/06/java-svg-to-bufferedimage/中窃取了这个答案。

编写一个简单的转码器

class BufferedImageTranscoder extends ImageTranscoder
{
  @Override
  public BufferedImage createImage(int w, int h)
  {
    BufferedImage bi = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB);
    return bi;
  }

  @Override
  public void writeImage(BufferedImage img, TranscoderOutput output)
  {
    this.img = img;
  }

  public BufferedImage getBufferedImage()
  {
    return img;
  }
  private BufferedImage img = null;
}

使用转码器

public static BufferedImage loadImage(File svgFile, float width, float height)
  {
    BufferedImageTranscoder imageTranscoder = new BufferedImageTranscoder();

    imageTranscoder.addTranscodingHint(PNGTranscoder.KEY_WIDTH, width);
    imageTranscoder.addTranscodingHint(PNGTranscoder.KEY_HEIGHT, height);

    TranscoderInput input = new TranscoderInput(svgFile);
    imageTranscoder.transcode(input, null);

    return imageTranscoder.getBufferedImage();
  }

然后,只需像显示 PNG 文件一样,在 JPanel 上显示已渲染的 BufferedImage


3
这将失去使用SVG图形的意义,您将失去图像的平滑缩放。 - Dodd10x
这取决于您的使用情况...即是否需要扩展。 - PaulProgrammer
此外,通过工作,您可以拦截会导致缩放的消息并进行必要的转换。 - PaulProgrammer
那会很慢。此外,如果您正在使用大型详细图像,则SVG文档将比BufferedImage消耗更少的内存。如果您只需要一个不需要缩放的BufferedImage,那么只需将图像转换为PNG或JPEG并完成即可。 - Dodd10x
我正在使用简单的SVG图像,最多只会更改一个图像,但大多数情况下它们是静止的。 - Jochem Kuijpers
@PaulProgrammer 我也遇到了同样的问题,想要栅格化一个包含图像(已经栅格化)的 SVG,但是抛出了无法栅格化的异常。有什么解决办法吗? - Mirwise Khan

8
使用Batik(http://xmlgraphics.apache.org/batik/)或SVGSalamander(https://svgsalamander.java.net/)。我以前成功使用过Batik,但我从未尝试过SVGSalamander。
在Batik中,有一个SVG面板可以为您显示图像并添加缩放、平移和旋转图像的键盘/鼠标快捷键。您可以禁用这些快捷键并实现自己的机制。
此外,通过一些工作,您可以重叠图像。
只要确保阅读常见问题解答。

谢谢!如果我需要帮助,我会发另一个问题的 :) - Jochem Kuijpers
没问题。如果您正在操作或使其交互,SVG可能会变得复杂,但仅显示它们应该很简单。两个链接都有示例。 - Dodd10x

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接