首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >使用PDFBox添加水印

使用PDFBox添加水印
EN

Stack Overflow用户
提问于 2012-01-20 00:50:25
回答 7查看 30.5K关注 0票数 22

我正在尝试添加一个水印的PDF格式,特别是与PDFBox。我已经能够让图像出现在每个页面上,但它失去了背景透明度,因为它看起来像是PDJpeg将其转换为JPG格式。也许有一种方法可以使用PDXObjectImage来实现。

到目前为止,我写了以下内容:

代码语言:javascript
运行
复制
public static void watermarkPDF(PDDocument pdf) throws IOException
{
    // Load watermark
    BufferedImage buffered = ImageIO.read(new File("C:\\PDF_Test\\watermark.png"));
    PDJpeg watermark = new PDJpeg(pdf, buffered);

    // Loop through pages in PDF
    List pages = pdf.getDocumentCatalog().getAllPages();
    Iterator iter = pages.iterator();
    while(iter.hasNext())
    {
        PDPage page = (PDPage)iter.next();

        // Add watermark to individual page
        PDPageContentStream stream = new PDPageContentStream(pdf, page, true, false);
        stream.drawImage(watermark, 100, 0);
        stream.close();
    }

    try 
    {
        pdf.save("C:\\PDF_Test\\watermarktest.pdf");
    } 
    catch (COSVisitorException e) 
    {
        e.printStackTrace();
    }
}
EN

回答 7

Stack Overflow用户

回答已采纳

发布于 2012-02-22 01:30:43

更新了ANSWER (更好的版本,提供了简单的水印方法,感谢下面的评论员和@okok提供了他的答案)

如果您使用的是PDFBox 1.8.10或更高版本,您可以轻松地添加水印到您的PDF文档,更好地控制哪些页面需要添加水印。假设您有一个带有水印图像的单页PDF文档,您可以将其覆盖在要添加水印的文档上,如下所示。

使用1.8.10的示例代码

代码语言:javascript
运行
复制
import java.util.HashMap;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.util.Overlay;

public class TestPDF {
    public static void main(String[] args) throws Exception{
            PDDocument realDoc = PDDocument.load("originaldocument.pdf"); 
            //the above is the document you want to watermark                   

            //for all the pages, you can add overlay guide, indicating watermark the original pages with the watermark document.
            HashMap<Integer, String> overlayGuide = new HashMap<Integer, String>();
            for(int i=0; i<realDoc.getPageCount(); i++){
                overlayGuide.put(i+1, "watermark.pdf");
                //watermark.pdf is the document which is a one page PDF with your watermark image in it. Notice here that you can skip pages from being watermarked.
            }
            Overlay overlay = new Overlay();
            overlay.setInputPDF(realDoc);
            overlay.setOutputFile("final.pdf");
            overlay.setOverlayPosition(Overlay.Position.BACKGROUND);
            overlay.overlay(overlayGuide,false);
           //final.pdf will have the original PDF with watermarks.

使用PDFBox 2.0.0候选版本的示例

代码语言:javascript
运行
复制
import java.io.File;
import java.util.HashMap;
import org.apache.pdfbox.multipdf.Overlay;
import org.apache.pdfbox.pdmodel.PDDocument;

public class TestPDF {

    public static void main(String[] args) throws Exception{        
        PDDocument realDoc = PDDocument.load(new File("originaldocument.pdf"));
        //the above is the document you want to watermark
        //for all the pages, you can add overlay guide, indicating watermark the original pages with the watermark document.

        HashMap<Integer, String> overlayGuide = new HashMap<Integer, String>();
        for(int i=0; i<realDoc.getNumberOfPages(); i++){
            overlayGuide.put(i+1, "watermark.pdf");
            //watermark.pdf is the document which is a one page PDF with your watermark image in it. 
            //Notice here, you can skip pages from being watermarked.
        }
        Overlay overlay = new Overlay();
        overlay.setInputPDF(realDoc);
        overlay.setOutputFile("final.pdf");
        overlay.setOverlayPosition(Overlay.Position.BACKGROUND);
        overlay.overlay(overlayGuide);      
    }
}

如果你想使用新的覆盖包org.apache.pdfbox.tools.OverlayPDF,你可以这样做。(感谢下面的海报)

代码语言:javascript
运行
复制
String[] overlayArgs = {"C:/Examples/foreground.pdf", "C:/Examples/background.pdf", "C:/Examples/resulting.pdf"};
OverlayPDF.main(overlayArgs);
System.out.println("Overlay finished.");

老答案效率低的方式,不推荐。

好的,OP询问如何在PDFBox中做到这一点,第一个答案看起来像使用iText的示例。在PDFBox中创建水印非常简单。诀窍是,您应该有一个带有水印图像的空PDF文档。然后,您所要做的就是将此水印文档覆盖在要添加水印的文档上。

代码语言:javascript
运行
复制
PDDocument watermarkDoc = PDDocument.load("watermark.pdf");
//Assuming your empty document with watermark image in it.

PDDocument realDoc = PDDocument.load("document-to-be-watermarked.pdf");
//Let's say this is your document that you want to watermark. For example sake, I am opening a new one, you would already have a reference to PDDocument if you are creating one

Overlay overlay = new Overlay();
overlay.overlay(realDoc,watermarkDoc);
watermarkDoc.save("document-now-watermarked.pdf");

注意:您应该确保两个document..Otherwise中的页数匹配,否则最终将得到一个页数与页数最少的文档相匹配的文档。您可以操作水印文档并复制页面以匹配您的文档。

希望这能帮上忙!

票数 36
EN

Stack Overflow用户

发布于 2013-12-17 02:30:11

我刚写了这段代码,用pdfbox把(透明的)图片(jpg,png,gif)添加到pdf页面:

代码语言:javascript
运行
复制
/**
 * Draw an image to the specified coordinates onto a single page. <br>
 * Also scaled the image with the specified factor.
 * 
 * @author Nick Russler
 * @param document PDF document the image should be written to.
 * @param pdfpage Page number of the page in which the image should be written to.
 * @param x X coordinate on the page where the left bottom corner of the image should be located. Regard that 0 is the left bottom of the pdf page.
 * @param y Y coordinate on the page where the left bottom corner of the image should be located.
 * @param scale Factor used to resize the image.
 * @param imageFilePath Filepath of the image that is written to the PDF.
 * @throws IOException
 */
public static void addImageToPage(PDDocument document, int pdfpage, int x, int y, float scale, String imageFilePath) throws IOException {   
    // Convert the image to TYPE_4BYTE_ABGR so PDFBox won't throw exceptions (e.g. for transparent png's).
    BufferedImage tmp_image = ImageIO.read(new File(imageFilePath));
    BufferedImage image = new BufferedImage(tmp_image.getWidth(), tmp_image.getHeight(), BufferedImage.TYPE_4BYTE_ABGR);        
    image.createGraphics().drawRenderedImage(tmp_image, null);

    PDXObjectImage ximage = new PDPixelMap(document, image);

    PDPage page = (PDPage)document.getDocumentCatalog().getAllPages().get(pdfpage);

    PDPageContentStream contentStream = new PDPageContentStream(document, page, true, true);
    contentStream.drawXObject(ximage, x, y, ximage.getWidth()*scale, ximage.getHeight()*scale);
    contentStream.close();
}

示例:

代码语言:javascript
运行
复制
public static void main(String[] args) throws Exception {
    String pdfFilePath = "C:/Users/Nick/Desktop/pdf-test.pdf";
    String signatureImagePath = "C:/Users/Nick/Desktop/signature.png";
    int page = 0;

    PDDocument document = PDDocument.load(pdfFilePath);

    addImageToPage(document, page, 0, 0, 0.5f, signatureImagePath);

    document.save("C:/Users/Nick/Desktop/pdf-test-neu.pdf");
}

这适用于jdk 1.7和bcmail-jdk16-140.jar、bcprov-jdk16-140.jar、commons-logging-1.1.3.jar、fontbox-1.8.3.jar、jempbox-1.8.3.jar和pdfbox-1.8.3.jar。

票数 10
EN

Stack Overflow用户

发布于 2017-09-12 02:57:25

@Androidman :添加到https://stackoverflow.com/a/9382212/7802973

似乎每个版本的PDFBox都删除了很多方法。因此该代码将不能在PDFBox 2.0.7上工作。

代码语言:javascript
运行
复制
Overlay overlay = new Overlay();
overlay.setInputPDF(realDoc);
// ** The method setOutputFile(String) is undefined for the type Overlay ** 
overlay.setOutputFile("final.pdf")

相反,我认为应该使用void org.apache.pdfbox.pdmodel.PDDocument.save(String fileName)

代码语言:javascript
运行
复制
PDDocument realDoc = PDDocument.load(new File("originaldocument.pdf"));
    //the above is the document you want to watermark
    //for all the pages, you can add overlay guide, indicating watermark the original pages with the watermark document.

HashMap<Integer, String> overlayGuide = new HashMap<Integer, String>();
    for(int i=0; i<realDoc.getNumberOfPages(); i++){
        overlayGuide.put(i+1, "watermark.pdf");
        //watermark.pdf is the document which is a one page PDF with your watermark image in it. 
        //Notice here, you can skip pages from being watermarked.
    }
Overlay overlay = new Overlay();
overlay.setInputPDF(realDoc);
overlay.overlay(overlayGuide).save("final.pdf");
overlay.close();

编辑:我现在正在使用org.apache.pdfbox.tools.OverlayPDF进行覆盖,它工作得很好。代码如下所示:

代码语言:javascript
运行
复制
String[] overlayArgs = {"C:/Examples/foreground.pdf", "C:/Examples/background.pdf", "C:/Examples/resulting.pdf"};
OverlayPDF.main(overlayArgs);
System.out.println("Overlay finished.");

由于我没有足够的名气来添加评论,我认为在新的答案中添加这一点是合适的。

票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/8929954

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档