java - 从 SVG 文件创建非缓冲的 java.awt.Image

标签 java svg batik

我有一些现有代码看起来很像 Swing & Batik: Create an ImageIcon from an SVG file? 上的解决方案

但是我的图像的目标是 PDF,这让我很烦恼,当您放大 PDF 时,您会看到像素。如果源数据和目标数据都是 vector 图形,应该可以直接渲染。

我们正在使用的库 (iText) 采用 java.awt.Image,但我似乎无法弄清楚如何获得呈现 SVG 的 java.awt.Image。 Batik 有办法做到这一点吗?

最佳答案

好吧,这就是我最终做的事情。 java.awt.Image 无疑是一条死胡同。有一个解决方案,将 PdfTemplate 包装在 ImgTemplate 中,这样它就可以用作 iText Image

(我必须把它放在知道它大小的东西中,因为它被用在表格中,否则布局会变得非常疯狂。Image 似乎知道这一点。)

public class SvgHelper {
    private final SAXSVGDocumentFactory factory;
    private final GVTBuilder builder;
    private final BridgeContext bridgeContext;

    public SvgHelper() {
        factory = new SAXSVGDocumentFactory(
            XMLResourceDescriptor.getXMLParserClassName());
        UserAgent userAgent = new UserAgentAdapter();
        DocumentLoader loader = new DocumentLoader(userAgent);
        bridgeContext = new BridgeContext(userAgent, loader);
        bridgeContext.setDynamicState(BridgeContext.STATIC);
        builder = new GVTBuilder();
    }

    public Image createSvgImage(PdfContentByte contentByte, URL resource,
                                float maxPointWidth, float maxPointHeight) {
        Image image = drawUnscaledSvg(contentByte, resource);
        image.scaleToFit(maxPointWidth, maxPointHeight);
        return image;
    }

    public Image drawUnscaledSvg(PdfContentByte contentByte, URL resource) {
        GraphicsNode imageGraphics;
        try {
            SVGDocument imageDocument = factory.createSVGDocument(resource.toString());
            imageGraphics = builder.build(bridgeContext, imageDocument);
        } catch (IOException e) {
            throw new RuntimeException("Couldn't load SVG resource", e);
        }

        float width = (float) imageGraphics.getBounds().getWidth();
        float height = (float) imageGraphics.getBounds().getHeight();

        PdfTemplate template = contentByte.createTemplate(width, height);
        Graphics2D graphics = template.createGraphics(width, height);
        try {
            // SVGs can have their corner at coordinates other than (0,0).
            Rectangle2D bounds = imageGraphics.getBounds();

            //TODO: Is this in the right coordinate space even?
            graphics.translate(-bounds.getX(), -bounds.getY());

            imageGraphics.paint(graphics);

            return new ImgTemplate(template);
        } catch (BadElementException e) {
            throw new RuntimeException("Couldn't generate PDF from SVG", e);
        } finally {
            graphics.dispose();
        }
    }
}

关于java - 从 SVG 文件创建非缓冲的 java.awt.Image,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13388706/

相关文章:

java - 编写超长字符串 csv header

java - 如何中止 Spring-Boot 启动?

javascript - 无论位置如何,如何获得一致的笔划宽度?

javascript - D3JS 包括以前的图例元素

java - batik-rasterizer.jar的调用方法

java - 如何拆分字符串,包括标点符号?

java - 如何从oracle数据库获取信息到java bean?

javascript - 如何复制 SVG 的内容并将其附加到另一个 SVG 框架?

java - Java SVG 图形界面中的属性修改

java - 使用 Java Batik 库的学习资源和教程