【发布时间】:2015-08-28 11:03:24
【问题描述】:
我使用了以下建议的代码:
为现有的 pdf 添加水印。 不幸的是,生成的 pdf 已损坏。当我打开文档时,pdf阅读器报错:“此页面存在错误。Acrobat 可能无法正确显示页面。请联系创建 PDF 文档的人以更正问题”。
文档已打开,但未显示图像。
这似乎发生在所有的 pdf 中。值得一提的是,它也发生在仅使用 Overlay 类的不同实现中。
以下网址指向我用于测试的 pdf:
测试这个转换的代码是:
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.apache.pdfbox.cos.COSDictionary;
import org.apache.pdfbox.cos.COSName;
import org.apache.pdfbox.exceptions.COSVisitorException;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.PDPage;
import org.apache.pdfbox.pdmodel.common.PDStream;
import org.apache.pdfbox.pdmodel.edit.PDPageContentStream;
import org.apache.pdfbox.pdmodel.graphics.PDExtendedGraphicsState;
import org.apache.pdfbox.pdmodel.graphics.xobject.PDXObjectForm;
import org.apache.pdfbox.util.MapUtil;
/**
* This test is about overlaying with special effect.
*
* @author mkl
*/
public class OverlayWithEffect
{
final static File RESULT_FOLDER = new File("target/test-outputs", "assembly");
public static 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)
{
if (page.getResources() == null) {
page.setResources(page.findResources());
}
if (page.getResources() != null) {
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();
}
}
}
public static 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;
}
public static void main(String[] args) throws COSVisitorException, IOException
{
InputStream sourceStream = new FileInputStream("x:/pdf-test.pdf");
InputStream overlayStream = new FileInputStream("x:/draft.pdf");
try {
final PDDocument document = PDDocument.load(sourceStream);
final PDDocument overlay = PDDocument.load(overlayStream);
overlayWithDarkenBlendMode(document, overlay);
document.save("x:/da-draft-5.pdf");
document.close();
}
finally {
sourceStream.close();
overlayStream.close();
}
}
}
我使用的是 pdfbox 1.7 版。
谢谢
【问题讨论】:
-
以下网址指向我用于测试的 pdf: - 是您用作水印的文档还是应应用水印的文档?你能提供(一个例子)缺少的吗?
-
我刚刚用自己的第一页覆盖了您的 PDF。因此,它已被用于两个角色。但是生成的 PDF 没有损坏,尤其是 Adobe Reader 不会抱怨。因此,您的描述缺少一些重现问题的信息。
-
非常感谢您花时间测试它。我使用的水印是:drive.google.com/file/d/0B7hG2Ap47MTKTjdfbzl5Q3pZUk0/…
-
使用您的共享文件我仍然无法重现该问题。 OverlayWithEffect.testOverlayWithDarkenMarcoAltieri2()将pdf-test.pdf与draft1.pdf叠加,结果符合预期。
-
使用您的确切代码(仅文件路径不同)和 PDFBox 1.8.10 我仍然无法重现您的问题。 OverlayWithEffect.main()将pdf-test.pdf与draft1.pdf叠加,结果符合预期。
标签: pdfbox