У меня возникла проблема с созданием многослойной pdf-страницы с использованием PdfBox. Я видел несколько сообщений здесь по этому вопросу, но они сосредоточены на импорте страниц из другого PDF в целевой документ.
Мое дело - бит-лит, отличный от другого (по крайней мере, я так думаю :)). Я создал класс MapImage, который содержит размер бумаги (в пикселях) и список BufferedImages, который я хочу добавить к одной странице PDF.
Вот код, который я пробовал:
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();
К сожалению, полученный PDF файл поврежден. Мне удалось создать страницу с одним изображением (без слоев), но, к сожалению, я понятия не имею, как это сделать.
Кто-нибудь столкнулся с такой проблемой?
Хорошо, я решил. Это метод, который делает то, что я хотел. Может быть, это будет полезно для кого-то :)
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;
}