2015-08-28 77 views
1

我已經使用了代碼提示圖像的PDF添加水印:在包含使用PDFBOX(1.7)

PDFBox Overlay fails

添加水印到現有的PDF。 不幸的是,生成的pdf已損壞。當我打開文檔時,pdf閱讀器抱怨:「此頁面存在錯誤,Acrobat可能無法正確顯示頁面,請聯繫創建PDF文檔的人以解決問題」

文檔已打開,但不顯示圖像。

它似乎發生在所有的PDF文件。值得一提的是,它也可以用一個不同的實現來簡單地使用Overlay類。

以下URL指向我用我的測試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

*以下url指向我用於測試的pdf:* - 是您用作水印的文檔,還是應該應用水印的文檔?你能提供一個(缺少的例子)嗎? – mkl

+2

我剛剛用自己的第一頁覆蓋了PDF。因此,它已被用於兩種角色。但生成的PDF是*不*損壞,尤其是Adobe Reader不抱怨。因此,您的描述缺少一些重現該問題的信息。 – mkl

+0

非常感謝您花時間對其進行測試。我使用的水印是:https://drive.google.com/file/d/0B7hG2Ap47MTKTjdfbzl5Q3pZUk0/view?usp=sharing –

回答

0

至於建議的MKL,它可能是與PDFBOX的版本,我使用的問題。