使用pdfbox(1.7)在包含图像的pdf上添加水印

时间:2015-08-28 11:03:25

标签: pdfbox

我使用了以下建议的代码:

PDFBox Overlay fails

为现有pdf添加水印。 不幸的是,生成的pdf已损坏。当我打开文档时,pdf阅读器会抱怨:“此页面上存在错误.Acrobat可能无法正确显示页面。请联系创建PDF文档的人员以解决问题”

文档已打开,但未显示图像。

似乎所有的pdf都会发生。值得一提的是,它只是使用Overlay类的不同实现。

以下网址指向我用于测试的pdf:

A pdf with an image

测试此转换的代码是:

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版本。

由于

1 个答案:

答案 0 :(得分:0)

正如mkl所建议的那样,我正在使用的pdfbox版本可能存在问题。