就像OP引用的问题一样(从 PDF iTextSharp 中删除水印),您可以通过构建从示例文件中删除水印PdfContentStreamEditor
我对这个问题的回答中提出了课程。
不过,与其他答案中的解决方案相反,我们不想根据某些透明度值隐藏矢量图形,而是从中写入“SID 存档”:
首先,我们必须选择一个标准来识别背景文本。让我们利用这样一个事实:这里的文字是迄今为止最大的。使用这个标准使得手头的任务本质上是 iTextSharp/C# 的挂件这个 iText/Java解决方案。
但有一个问题:正如该答案中提到的:
The 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"};
}
The 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);
}
}
}
您的示例文件结果为: