Add a watermark on a pdf that contains images using pdfbox (1.7)

白昼怎懂夜的黑 提交于 2020-01-05 08:41:58

问题


I have used the code suggested in:

PDFBox Overlay fails

to add a watermark to an existing pdf. Unfortunately, the pdf produced is corrupted. The pdf reader complains when I open the document: "An error exists on this page. Acrobat may not display the page correctly. Please contact the person who created the PDF document to correct the problem".

The document is opened but it does not show the images.

It seems to happen with all the pdfs. It could be worth saying that it happens also with a different implementation that simply uses the Overlay class.

The following url points to a pdf that I used for my testing:

A pdf with an image

The code to test this transformation is:

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();
        }
    }    
}

I am using version 1.7 of pdfbox.

Thanks


回答1:


As suggested by mkl, it is probably an issue with the version of pdfbox that I am using.



来源:https://stackoverflow.com/questions/32269571/add-a-watermark-on-a-pdf-that-contains-images-using-pdfbox-1-7

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!