[英]How to generate layered pdf file using PdfBox?
I have a problem with generating a layered pdf page using PdfBox.我在使用 PdfBox 生成分层 pdf 页面时遇到问题。 I have seen several posts here on the subject, but they focus on importing pages from another pdf to a target document.
我在这里看过几篇关于这个主题的帖子,但他们专注于将页面从另一个 pdf 导入目标文档。
My case is a liitle bit different (at least I think so:) ).我的情况有点不同(至少我是这么认为的:))。 I created a class MapImage that contains the paper size (in pixels) and a list of BufferedImages' that I want to add to a single pdf page.
我创建了一个 class MapImage,其中包含纸张大小(以像素为单位)和我想添加到单个 pdf 页面的 BufferedImages 列表。
Here is the code that I tried:这是我尝试过的代码:
ByteArrayOutputStream baos = new ByteArrayOutputStream();
PDDocument document = new PDDocument();
for (MapImage image : images) {
PDPage page = new PDPage(new PDRectangle(image.getPaperWidth(), image.getPaperHeight()));
page.setResources(new PDResources(new COSDictionary()));
document.addPage(page);
LayerUtility layerUtility = new LayerUtility(document);
int i=1;
for(BufferedImage layer : image.getLayers()) {
PDJpeg img = new PDJpeg(document, layer);
layerUtility.appendFormAsLayer(page, new PDXObjectForm(img.getCOSStream()), new AffineTransform(), "Layer " + i++);
}
}
document.save(baos);
document.close();
Unfortunately the resulting PDF is corrupted.不幸的是,生成的 PDF 已损坏。 I manged to create a page with only one image (with no layers) but unfortunately I have no idea how to do this.
我设法创建一个只有一个图像(没有图层)的页面,但不幸的是我不知道如何做到这一点。
Did anyone have come accross such problem?有没有人遇到过这样的问题?
OK, I solved it. 好的,我解决了。 This is the method that does what I wanted.
这是做我想要的方法。 Maybe it will be useful for someone :)
也许对某人有用:)
public static PDOptionalContentGroup appendImageAsLayer(PDDocument document, PDPage targetPage, BufferedImage image, String layerName) throws IOException {
PDDocumentCatalog catalog = document.getDocumentCatalog();
PDOptionalContentProperties ocprops = catalog.getOCProperties();
if (ocprops == null) {
ocprops = new PDOptionalContentProperties();
catalog.setOCProperties(ocprops);
}
if (ocprops.hasGroup(layerName)) {
throw new IllegalArgumentException("Optional group (layer) already exists: " + layerName);
}
PDOptionalContentGroup layer = new PDOptionalContentGroup(layerName);
ocprops.addGroup(layer);
PDResources resources = targetPage.findResources();
if(resources == null ) {
resources = new PDResources(new COSDictionary());
targetPage.setResources(resources);
}
PDPropertyList props = resources.getProperties();
if (props == null) {
props = new PDPropertyList();
resources.setProperties(props);
}
// Find first free resource name with the pattern "MC<index>"
int index = 0;
PDOptionalContentGroup ocg;
COSName resourceName;
do {
resourceName = COSName.getPDFName("MC" + index);
ocg = props.getOptionalContentGroup(resourceName);
index++;
} while (ocg != null);
// Put mapping for our new layer/OCG
props.putMapping(resourceName, layer);
PDJpeg img = new PDJpeg(document, image);
PDPageContentStream contentStream = new PDPageContentStream(document, targetPage, true, false);
contentStream.beginMarkedContentSequence(COSName.OC, resourceName);
contentStream.drawImage(img, 0, 0);
contentStream.endMarkedContentSequence();
contentStream.close();
return layer;
}
For PDFBox 2.0:对于 PDFBox 2.0:
public static PDOptionalContentGroup appendImageAsLayer(PDDocument doc, PDPage page,
PDImageXObject pdImage, AffineTransform transform,
String layerName) throws IOException {
PDDocumentCatalog catalog = doc.getDocumentCatalog();
PDOptionalContentProperties ocprops = catalog.getOCProperties();
if (ocprops == null) {
ocprops = new PDOptionalContentProperties();
catalog.setOCProperties(ocprops);
}
PDOptionalContentGroup layer = ocprops.getGroup(layerName);
if (layer == null) {
layer = new PDOptionalContentGroup(layerName);
ocprops.addGroup(layer);
}
try (PDPageContentStream contentStream = new PDPageContentStream(
doc, page, PDPageContentStream.AppendMode.APPEND, false)) {
contentStream.beginMarkedContent(COSName.OC, layer);
contentStream.saveGraphicsState();
contentStream.transform(new Matrix(transform));
contentStream.drawImage(pdImage, 0, 0, pdImage.getWidth(), pdImage.getHeight());
contentStream.restoreGraphicsState();
contentStream.endMarkedContent();
}
return layer;
}
PDImageXObject can be created using:可以使用以下方法创建 PDImageXObject:
PDImageXObject pdImage = PDImageXObject.createFromFile(imagePath, doc);
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.