【问题标题】:Create a non-buffered java.awt.Image from an SVG file从 SVG 文件创建非缓冲 java.awt.Image
【发布时间】:2012-11-03 12:46:48
【问题描述】:

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

但是我的图像的目的地是 PDF,当你放大 PDF 时,你会看到像素,这让我很困扰。如果源数据和目标数据都是矢量图形,应该可以直接渲染。

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

【问题讨论】:

  • 将 SVG 图像转换为 java.awt.Image 会将 SVG 转换为 SVG 的像素表示,它不会保留矢量信息。我不知道它是否会有所帮助,但您可能想看看this,这是我在 Google 上获得的“iText SVG”的第一个热门
  • Hmm... 转换成 java.awt.BufferedImage 至少会丢掉向量信息,但我的印象是因为 java.awt.Image 是抽象的,所以不应该画一个取决于分辨率。
  • Image 仍然由像素数据支持(在大多数情况下),尤其是在渲染到图形上下文时
  • 是的,因为它是“在大多数情况下”,我认为剩下的一种情况可以让我用 SVG 来支持它。 :) 至于那个例子,PdfGraphics2D 的构造函数是私有的。我猜这是针对不同版本的 iText,但我认为我们是最新的。
  • 要让Image 在 iText 中工作,iText 需要提供实现,因为 iText 只知道如何在给定的上下文中绘制它。

标签: java svg batik


【解决方案1】:

好吧,这就是我最终要做的。 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();
        }
    }
}

【讨论】:

    猜你喜欢
    • 2013-09-23
    • 2012-02-08
    • 2018-03-15
    • 2015-05-09
    • 1970-01-01
    • 2010-09-29
    • 2022-12-14
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多