如何使用文本或图像为PDF水印?

Len*_*and 6 java pdf

我在一个文件夹中有一堆PDF文档,我想用水印来增加它们.Java服务器上下文有哪些选择?

优选地,水印将支持透明度.矢量和光栅都是可取的.

Bru*_*gie 7

请查看TransparentWatermark2示例.它在每个奇数页面上添加透明文本,在现有PDF文档的每个偶数页面上添加透明图像.

这就是它的完成方式:

public void manipulatePdf(String src, String dest) throws IOException, DocumentException {
    PdfReader reader = new PdfReader(src);
    int n = reader.getNumberOfPages();
    PdfStamper stamper = new PdfStamper(reader, new FileOutputStream(dest));
    // text watermark
    Font f = new Font(FontFamily.HELVETICA, 30);
    Phrase p = new Phrase("My watermark (text)", f);
    // image watermark
    Image img = Image.getInstance(IMG);
    float w = img.getScaledWidth();
    float h = img.getScaledHeight();
    // transparency
    PdfGState gs1 = new PdfGState();
    gs1.setFillOpacity(0.5f);
    // properties
    PdfContentByte over;
    Rectangle pagesize;
    float x, y;
    // loop over every page
    for (int i = 1; i <= n; i++) {
        pagesize = reader.getPageSizeWithRotation(i);
        x = (pagesize.getLeft() + pagesize.getRight()) / 2;
        y = (pagesize.getTop() + pagesize.getBottom()) / 2;
        over = stamper.getOverContent(i);
        over.saveState();
        over.setGState(gs1);
        if (i % 2 == 1)
            ColumnText.showTextAligned(over, Element.ALIGN_CENTER, p, x, y, 0);
        else
            over.addImage(img, w, 0, 0, h, x - (w / 2), y - (h / 2));
        over.restoreState();
    }
    stamper.close();
    reader.close();
}
Run Code Online (Sandbox Code Playgroud)

如您所见,我们Phrase为文本创建了一个Image对象,为该图像创建了一个对象.我们还PdfGState为透明度创建了一个对象.在我们的例子中,我们采用50%的不透明度(将其0.5f改为其他东西以进行实验).

一旦我们拥有了这些对象,我们就会遍历每一页.我们使用该PdfReader对象来获取有关现有文档的信息,例如每个页面的维度.PdfStamper当我们想要在现有文档上标记额外内容时,我们使用该对象,例如在每个页面的顶部添加水印.

更改图形状态时,saveState()在开始之前和restoreState()完成之后执行a总是安全的.如果你不这样做,你的代码可能也会有用,但请相信我:如果你采用这个规则来节省大量的调试时间,因为如果图形状态不平衡你会得到非常奇怪的效果.

我们使用该setGState()方法应用透明度,并根据页面是奇数页还是偶数页,我们添加文本(使用ColumnText(x, y)计算的坐标,以便在每个页面的中间添加文本)或图像(使用addImage()转换矩阵的方法和适当的参数).

一旦你为文档中的每个页面完成了这个,你必须close()得到stamperreader.

警告:

您会注意到第3页和第4页是横向的,但肉眼看不到的这两页之间存在差异.第3页实际上是一个页面,其大小定义为纵向页面,但它旋转了90度.第4页是一个页面,其大小的定义方式是宽度>高度.

这会对添加水印的方式产生影响,但如果使用getPageSizeWithRotation(),iText将适应.这可能不是您想要的:也许您希望以不同方式添加水印.

看一下TransparentWatermark3:

public void manipulatePdf(String src, String dest) throws IOException, DocumentException {
    PdfReader reader = new PdfReader(src);
    int n = reader.getNumberOfPages();
    PdfStamper stamper = new PdfStamper(reader, new FileOutputStream(dest));
    stamper.setRotateContents(false);
    // text watermark
    Font f = new Font(FontFamily.HELVETICA, 30);
    Phrase p = new Phrase("My watermark (text)", f);
    // image watermark
    Image img = Image.getInstance(IMG);
    float w = img.getScaledWidth();
    float h = img.getScaledHeight();
    // transparency
    PdfGState gs1 = new PdfGState();
    gs1.setFillOpacity(0.5f);
    // properties
    PdfContentByte over;
    Rectangle pagesize;
    float x, y;
    // loop over every page
    for (int i = 1; i <= n; i++) {
        pagesize = reader.getPageSize(i);
        x = (pagesize.getLeft() + pagesize.getRight()) / 2;
        y = (pagesize.getTop() + pagesize.getBottom()) / 2;
        over = stamper.getOverContent(i);
        over.saveState();
        over.setGState(gs1);
        if (i % 2 == 1)
            ColumnText.showTextAligned(over, Element.ALIGN_CENTER, p, x, y, 0);
        else
            over.addImage(img, w, 0, 0, h, x - (w / 2), y - (h / 2));
        over.restoreState();
    }
    stamper.close();
    reader.close();
}
Run Code Online (Sandbox Code Playgroud)

在这种情况下,我们不会getPageSizeWithRotation()简单地使用getPageSize().我们还告诉stamper 不要补偿现有的页面轮换:stamper.setRotateContents(false);

看看生成的PDF中的差异:

在第一个屏幕截图中(显示生成的PDF的第3页和第4页TransparentWatermark2),左边的页面实际上是一个纵向旋转90度的页面.但是,iText将其视为横向页面,就像右侧页面一样.

在此输入图像描述

在第二个屏幕截图中(显示生成的PDF的第3页和第4页TransparentWatermark3),左边的页面是纵向旋转90度的页面,我们添加水印,就好像页面是纵向的一样.结果,水印也旋转了90度.右侧页面不会发生这种情况,因为该页面的旋转度为0度.

在此输入图像描述

这是一个微妙的区别,但我想你想知道.

如果你想用法语阅读这个答案,请阅读评论créerunfiligrane transparent en PDF?