使用itextsharp删除基于文本的水印

时间:2016-05-17 18:07:27

标签: c# pdf itextsharp

根据这篇文章(Removing Watermark from PDF iTextSharp),@ mkl代码适用于ExGstate图形水印,但我已经测试了这段代码,从一些文件中删除了水印,这些文件在PDF内容后面有基于文本的水印(比如这个文件:{ {3}}) 我尝试过在本网站上找到的多种解决方案,但没有成功。 任何人都可以通过更改上面的@mkl解决方案来帮助删除这些水印类型吗?

感谢

1 个答案:

答案 0 :(得分:1)

就像OP引用的问题(Removing Watermark from PDF iTextSharp)一样,您可以通过我对该问题的回答中提供的PdfContentStreamEditor类来删除示例文件中的水印。 / p>

与其他答案中的解决方案相比,我们不希望隐藏基于某些透明度值的矢量图形,而是写入"存档的SID"从这个:

sid-1.pdf

首先,我们必须选择一个标准来识别背景文字。让我们使用这样一个事实,即写作是迄今为止最大的。使用此标准使得手头的任务基本上成为this iText/Java解决方案的iTextSharp / C#链接。

但是有一个问题:如答案所述:

  

第二个样本中使用的gs().getFontSize()可能与您预期的不同,因为有时坐标系已被当前变换矩阵和文本矩阵拉伸。可以扩展代码以考虑这些影响。

这里恰好发生这种情况:使用字体大小为1,然后通过文本矩阵拉伸小文本:

/NxF0 1 Tf
49.516754 49.477234 -49.477234 49.516754 176.690933 217.316086 Tm

因此,我们需要考虑文本矩阵。不幸的是,文本矩阵是私人成员。因此,我们还需要一些反思魔法。

因此,该文件的可能背景去除器如下所示:

class BigTextRemover : PdfContentStreamEditor
{
    protected override void Write(PdfContentStreamProcessor processor, PdfLiteral operatorLit, List<PdfObject> operands)
    {
        if (TEXT_SHOWING_OPERATORS.Contains(operatorLit.ToString()))
        {
            Vector fontSizeVector = new Vector(0, Gs().FontSize, 0);
            Matrix textMatrix = (Matrix) textMatrixField.GetValue(this);
            Matrix curentTransformationMatrix = Gs().GetCtm();
            Vector transformedVector = fontSizeVector.Cross(textMatrix).Cross(curentTransformationMatrix);
            float transformedFontSize = transformedVector.Length;
            if (transformedFontSize > 40)
                return;
        }
        base.Write(processor, operatorLit, operands);
    }
    System.Reflection.FieldInfo textMatrixField = typeof(PdfContentStreamProcessor).GetField("textMatrix", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
    List<string> TEXT_SHOWING_OPERATORS = new List<string>{"Tj", "'", "\"", "TJ"};
}

选择40并考虑到该文本矩阵。

像这样应用

[Test]
public void testRemoveBigText()
{
    string source = @"sid-1.pdf";
    string dest = @"sid-1-noBigText.pdf";

    using (PdfReader pdfReader = new PdfReader(source))
    using (PdfStamper pdfStamper = new PdfStamper(pdfReader, new FileStream(dest, FileMode.Create, FileAccess.Write)))
    {
        PdfContentStreamEditor editor = new BigTextRemover();

        for (int i = 1; i <= pdfReader.NumberOfPages; i++)
        {
            editor.EditPage(pdfStamper, i);
        }
    }
}

到您的示例文件结果为:

sid-1-noBigText.pdf