2

Swing & Batikのソリューションによく似た既存のコードがいくつかあります: SVG ファイルから ImageIcon を作成しますか?

しかし、私の画像の宛先は PDF であり、PDF を拡大するとピクセルが表示されるのが気になります。ソース データと宛先データが両方ともベクター グラフィックである場合は、直接レンダリングできるはずです。

私たちが使用しているライブラリ (iText) は java.awt.Image を取りますが、SVG をレンダリングする java.awt.Image を取得する方法がわかりません。バティックにはそれを行う方法がありますか?

4

1 に答える 1

1

さて、これが私がやったことです。java.awt.Image確かに行き止まりだった。PdfTemplateaを anでラップしてImgTemplateiText として使えるようにするという形で解決策がありました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();
        }
    }
}
于 2012-11-15T04:08:02.620 に答える