简体   繁体   English

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

[英]Create a non-buffered java.awt.Image from an SVG file

I have some existing code which looks a lot like the solution on Swing & Batik: Create an ImageIcon from an SVG file? 我有一些现有的代码,看起来与Swing和Batik上的解决方案非常相似:从SVG文件创建ImageIcon?

But the destination for my image is PDF, and it bugs me that when you zoom into the PDF, you see pixels. 但是我的图像的目的地是PDF,这使我感到困惑,当您放大PDF时会看到像素。 If the source and destination data are both vector graphics, it should be possible to render directly. 如果源数据和目标数据都是矢量图形,则应该可以直接进行渲染。

The library we're using (iText) takes a java.awt.Image, but I can't seem to figure out how to get a java.awt.Image which renders an SVG. 我们正在使用的库(iText)接受一个java.awt.Image,但是我似乎无法弄清楚如何获取呈现SVG的java.awt.Image。 Does Batik have some way to do that? 蜡染有办法做到吗?

Well, here's what I ended up doing. 好吧,这就是我最终要做的。 java.awt.Image was certainly a dead-end. java.awt.Image当然是死路一条。 There was a solution in the form of wrapping up a PdfTemplate in an ImgTemplate so that it could be used as an iText Image . 有在结束了一个形式的溶液PdfTemplateImgTemplate ,以便它可被用作一个iText的Image

(I had to have it in something which knew its size, because it's being used in a table and the layout would go completely crazy otherwise. An Image seems to know this.) (我必须将它放在一个知道其大小的东西中,因为它正被用在表中,否则布局会完全发疯。否则, 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();
        }
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM