2013-07-08 79 views
7

我使用C#和iTextSharp的添加水印到我的PDF文件:如何在PDF文件上添加水印?

Document document = new Document(); 
PdfReader pdfReader = new PdfReader(strFileLocation); 
PdfStamper pdfStamper = new PdfStamper(pdfReader, new FileStream(strFileLocationOut, FileMode.Create, FileAccess.Write, FileShare.None)); 
iTextSharp.text.Image img = iTextSharp.text.Image.GetInstance(WatermarkLocation); 
img.SetAbsolutePosition(100, 300); 
PdfContentByte waterMark; 
//  
for (int pageIndex = 1; pageIndex <= pdfReader.NumberOfPages; pageIndex++) 
{ 
    waterMark = pdfStamper.GetOverContent(pageIndex); 
    waterMark.AddImage(img); 
} 
// 
pdfStamper.FormFlattening = true; 
pdfStamper.Close(); 

它工作正常,但我的问题是,在某些PDF文件中没有添加水印虽然文件大小增加,任何想法?

+0

是否所有的PDF文件都具有相同的mediabox和cropbox?难道是位置'(100,300)'在这些箱子外面吗? –

+0

的位置是正确的,我测试它。 – Abady

+0

当没有水印可见时,媒体/裁切框的坐标是什么? –

回答

7

文件大小增加这一事实很好地表明添加了水印。主要的问题是您要在页面的可见区域外添加水印。见How to position text relative to page using iText?

你需要的东西是这样的:

Rectangle pagesize = reader.GetCropBox(pageIndex); 
if (pagesize == null) 
    pagesize = reader.GetMediaBox(pageIndex); 
img.SetAbsolutePosition(
    pagesize.GetLeft(), 
    pagesize.GetBottom()); 

那就是:如果你想在页面的左下角添加图像。您可以添加偏移量,但要确保x方向上的偏移量不超过页面宽度,并且y方向上的偏移量不会超过页面高度。

+1

在Nuget的iText LGPL ver 4.1.6中,没有'pdfReader.GetMediaBox(pageNumber)',而是有'pdfReader.GetPageSize(pageNumber)'。 'pageIndex'也给出它以'0开头的印象。由于它以'1'开始,因此'pageNumber'会更好。 –

+0

@RosdiKasim虽然我不同意那个pageIndex意味着基于0的索引,但您确定GetMediaBox()是错误的方法....您应该将此编辑添加到答案中,以便它更加正确。 GetCropBox也是getCropBox的正确框架 – Arkaine55

0

虽然我不知道iTextSharp的具体情况,但很可能在未显示图像的页面上,以前的PDF内容已经修改了当前的转换矩阵,以便您放在页面上的任何内容都会从页面上移开。

这可以通过在原始页面内容之前发出gsave运算符并在原始页面内容(但在您之前)发出grestore运算符来解决。但是,这可能无法修复所有使用修改CTM的PDF文档执行gsave和grestore的情况。根据PDF规范,理论上不会发生这种情况:

q和Q运算符的出现应在给定内容流内(或在页面字典的内容数组中指定的流序列内平衡) )。

但我可以从经验告诉你,实际情况并非如此。

+0

OP使用'pdfStamper.GetOverContent'这意味着iText将** q **和** Q **中的现有内容流封装起来,然后在** q ... Q **之外添加OP的添加内容,因此,不受任何此类CTM变化的影响。我认为@Alexis的假设是正确的。 – mkl