使用PDFBox在PDF上绘制矢量图像 [英] Drawing vector images on PDF with PDFBox
问题描述
我想用Apache PDFBox在PDF上绘制矢量图像.
I would like to draw a vector image on a PDF with Apache PDFBox.
这是我用来绘制常规图像的代码
This is the code I use to draw regular images
PDPage page = (PDPage) document.getDocumentCatalog().getAllPages().get(1);
PDPageContentStream contentStream = new PDPageContentStream(document, page, true, true);
BufferedImage _prevImage = ImageIO.read(new FileInputStream("path/to/image.png"));
PDPixelMap prevImage = new PDPixelMap(document, _prevImage);
contentStream.drawXObject(prevImage, prevX, prevY, imageWidth, imageHeight);
如果我使用svg
或wmf
图像而不是png,则生成的PDF文档将损坏.
If I use a svg
or wmf
image instead of png, the resulting PDF document comes corrupted.
我希望该图像为矢量图像的主要原因是,使用PNG或JPG时,该图像看起来很糟糕,我认为它已经以某种方式被压缩,因此看起来很糟糕.对于矢量图像,这种情况不应该发生(嗯,当我在Inkscape中将svg路径导出为PDF时,这种情况不会发生,矢量路径会保留下来.)
The main reason I want the image to be a vector image is that with PNG or JPG the image looks horrible, I think it gets somehow compressed so it looks bad. With vector images this shouldn't happen (well, when I export svg paths as PDF in Inkscape it doesn't happen, vector paths are preserved).
是否可以使用Apache PDFBox将svg或wmf(或其他矢量)绘制为PDF?
Is there a way to draw a svg or wmf (or other vector) to PDF using Apache PDFBox?
如果这很重要,我目前正在使用PDFBox 1.8.
I'm currently using PDFBox 1.8, if that matters.
推荐答案
请参见库 pdfbox-graphics2d ,此Jira 中被吹捧.
您可以通过蜡染或
You can draw the SVG, via Batik or Salamander or whatever, onto the class PdfBoxGraphics2D
, which is parallel to iText's template.createGraphics()
. See the GitHub page for samples.
PDDocument document = ...;
PDPage page = ...; // page whereon to draw
String svgXML = "<svg>...</svg>";
double leftX = ...;
double bottomY = ...; // PDFBox coordinates are oriented bottom-up!
// I set these to the SVG size, which I calculated via Salamander.
// Maybe it doesn't matter, as long as the SVG fits on the graphic.
float graphicsWidth = ...;
float graphicsHeight = ...;
// Draw the SVG onto temporary graphics.
var graphics = new PdfBoxGraphics2D(document, graphicsWidth, graphicsHeight);
try {
int x = 0;
int y = 0;
drawSVG(svg, graphics, x, y); // with Batik, Salamander, or whatever you like
} finally {
graphics.dispose();
}
// Graphics are not visible till a PDFormXObject is added.
var xform = graphics.getXFormObject();
try (var contentWriter = new PDPageContentStream(document, page, AppendMode.APPEND, false)) { // false = don't compress
// XForm objects have to be placed via transform,
// since they cannot be placed via coordinates like images.
var transform = AffineTransform.getTranslateInstance(leftX, bottomY);
xform.setMatrix(transform);
// Now the graphics become visible.
contentWriter.drawForm(xform);
}
还有...如果您还想将SVG图形缩放到25%大小:
And ... in case you want also to scale the SVG graphics to 25% size:
// Way 1: Scale the SVG beforehand
svgXML = String.format("<svg transform=\"scale(%f)\">%s</svg>", .25, svgXML);
// Way 2: Scale in the transform (before calling xform.setMatrix())
transform.concatenate(AffineTransform.getScaleInstance(.25, .25));
这篇关于使用PDFBox在PDF上绘制矢量图像的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!