我有一些现有代码,看起来很像Swing & Batik 上的解决方案:从 SVG 文件创建 ImageIcon?
但是我的图像的目的地是 PDF,当你放大 PDF 时,你会看到像素,这让我很烦恼。如果源数据和目标数据都是矢量图形,应该可以直接渲染。
我们正在使用的库(iText)采用 java.awt.Image,但我似乎无法弄清楚如何获取呈现 SVG 的 java.awt.Image。蜡染有办法做到这一点吗?
我有一些现有代码,看起来很像Swing & Batik 上的解决方案:从 SVG 文件创建 ImageIcon?
但是我的图像的目的地是 PDF,当你放大 PDF 时,你会看到像素,这让我很烦恼。如果源数据和目标数据都是矢量图形,应该可以直接渲染。
我们正在使用的库(iText)采用 java.awt.Image,但我似乎无法弄清楚如何获取呈现 SVG 的 java.awt.Image。蜡染有办法做到这一点吗?
好吧,这就是我最终要做的。java.awt.Image
肯定是一条死胡同。有一个解决方案是将 a 包装PdfTemplate
在 an 中,ImgTemplate
以便它可以用作 iText Image
。
(我必须把它放在知道它大小的东西里,因为它被用在桌子上,否则布局会变得非常疯狂。AnImage
似乎知道这一点。)
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();
}
}
}