问题
I use PDFBox 1.8.8 and try to overlay a PDDocument with an other document by using the following scala method
def mergeTest() = {
val home = System.getProperty("user.home")
val doc = PDDocument.load(home + "/tmp/document.pdf")
val ovl = PDDocument.load(home + "/tmp/overlay.pdf")
val ov = new Overlay()
val mergeDoc = ov.overlay(ovl, doc)
mergeDoc.save(home + "/tmp/result.pdf")
doc.close()
ovl.close()
mergeDoc.close()
}
I have expected to get every page of "document.pdf" (N pages) overlayed with the content of "overlay.pdf" (1 page).
As a result in "result.pdf" there are as many pages as in "document.pdf", however the original content of "document.pdf" is completely overwritten by the content of the overlay.
回答1:
The cause
The OP's overlay.pdf page content starts with
/Cs1 cs
1 sc
0.1400146 841.945 m
595.14 841.945 l
595.14 -0.05499268 l
0.1400146 -0.05499268 l
h
f
0.1400146 841.945 m
595.14 841.945 l
595.14 -0.05499268 l
0.1400146 -0.05499268 l
h
f
These operations draw two white (CS1 is a grayscale color space) rectangles covering nearly the whole MediaBox [0, 0, 595.28, 841.89]
with the exception of a very slim line at the top and at the left
Laying this page content over another page, therefore, completely covers all existing content of that other page which is exactly what you have observed:
the original content of "document.pdf" is completely overwritten by the content of the overlay
It usually only makes sense to overlay with a page which does not cover everything.
A work-around using blend mode Darken
Alternatively you might want to try overlaying using the blend mode Darken which selects the darker of the backdrop and source colours, the backdrop is replaced with the source where the source is darker; otherwise, it is left unchanged.
In Java (I have no experience with Scala, so I hope you can make use of Java source) you can use methods like these:
void overlayWithDarkenBlendMode(PDDocument document, PDDocument overlay) throws IOException { PDXObjectForm xobject = importAsXObject(document, (PDPage) overlay.getDocumentCatalog().getAllPages().get(0)); PDExtendedGraphicsState darken = new PDExtendedGraphicsState(); darken.getCOSDictionary().setName("BM", "Darken"); List<PDPage> pages = document.getDocumentCatalog().getAllPages(); for (PDPage page: pages) { Map<String, PDExtendedGraphicsState> states = page.getResources().getGraphicsStates(); if (states == null) states = new HashMap<String, PDExtendedGraphicsState>(); String darkenKey = MapUtil.getNextUniqueKey(states, "Dkn"); states.put(darkenKey, darken); page.getResources().setGraphicsStates(states); PDPageContentStream stream = new PDPageContentStream(document, page, true, false, true); stream.appendRawCommands(String.format("/%s gs ", darkenKey)); stream.drawXObject(xobject, 0, 0, 1, 1); stream.close(); } } PDXObjectForm importAsXObject(PDDocument target, PDPage page) throws IOException { final PDStream xobjectStream = new PDStream(target, page.getContents().createInputStream(), false); final PDXObjectForm xobject = new PDXObjectForm(xobjectStream); xobject.setResources(page.findResources()); xobject.setBBox(page.findCropBox()); COSDictionary group = new COSDictionary(); group.setName("S", "Transparency"); group.setBoolean(COSName.getPDFName("K"), true); xobject.getCOSStream().setItem(COSName.getPDFName("Group"), group); return xobject; }
(OverlayWithEffect.java)
Applying them to your sample documents
@Test
public void testOverlayWithDarkenVolker() throws COSVisitorException, IOException
{
try ( InputStream sourceStream = getClass().getResourceAsStream("document1.pdf");
InputStream overlayStream = getClass().getResourceAsStream("overlay.pdf") )
{
final PDDocument document = PDDocument.load(sourceStream);
final PDDocument overlay = PDDocument.load(overlayStream);
overlayWithDarkenBlendMode(document, overlay);
document.save(new File(RESULT_FOLDER, "document1-with-overlay.pdf"));
}
}
results in
As you see, both the numbers from document1.pdf and the lines from overlay.pdf are there.
Beware! This code is a proof-of-concept and not ready for general productive use. It e.g. completely ignores Rotate page entries...
来源:https://stackoverflow.com/questions/29095822/pdfbox-overlay-fails