在下面的代码中,我尝试在现有文本上放置一层文本(原始现有文本为"隐藏"通过将其写成白色字体;它用作此替换的占位符处理)。下面的代码非常依赖于Chris Haas在这篇文章中提供的代码:
然而,"左"我的文字放置的位置很好,但是"底部"低于我尝试覆盖的文本(即使字体相同)。如何更改此选项以获取原始文档中文本的正确坐标?原始文档是使用表格进行布局创建的,因此这会影响这个"覆盖"过程
byte[] content;
string tmppath = @"C:\Junk\MSE_1.pdf";
using (MemoryStream output = new MemoryStream())
{
PdfReader pdf_rdr = new PdfReader(tmppath);
PdfStamper stamper = new PdfStamper(pdf_rdr, output);
for (int i = 1; i < pdf_rdr.NumberOfPages; i++)
{
//Create an instance of our strategy
var t = new MyLocationTextExtractionStrategy("stuff");
if (t != null)
{
//Parse the page of the document above
//(if the text was found)
var ex = PdfTextExtractor.GetTextFromPage(pdf_rdr, i, t);
//Loop through each chunk found
foreach (var p in t.myPoints)
{
Console.WriteLine(string.Format("Found text {0} at {1} x {2} on page {3}", p.Text, p.Rect.Left, p.Rect.Bottom, i.ToString()));
PdfContentByte pcb = stamper.GetOverContent(i);
pcb.BeginText();
try
{
BaseFont bf = BaseFont.CreateFont(@"C:\Junk\FontFiles\georgia.ttf", BaseFont.IDENTITY_H, BaseFont.EMBEDDED);
pcb.SetFontAndSize(bf, 10);
pcb.SetTextMatrix(p.Rect.Left, p.Rect.Bottom);
//pcb.SetTextRise(3);
pcb.ShowText("STUFF");
}
finally
{
pcb.EndText();
}
}
}
}
// Set the flattening flag to true, as the editing is done
stamper.FormFlattening = true;
// close the pdf stamper
stamper.Close();
//close the PDF reader
pdf_rdr.Close();
//put the output into the byte array
content = output.ToArray();
}
//write the content to a PDF file
using (FileStream fs = File.Create(@"C:\Junk\MSE_REPLACED.pdf"))
{
fs.Write(content, 0, (int)content.Length);
fs.Flush();
}
答案 0 :(得分:2)
克里斯&#39; MyLocationTextExtractionStrategy
只考虑文本片段的下降线和上升线,因为它对字符串使用的区域感兴趣。
但是,对于您的任务,您需要基线,因为文本绘制操作使用当前位置作为基线开始。
因此,你应该创建一个Chris&#39;的变体。除了上升和下降线之外,管理文本基线而不是/的类。
PS: OP在评论中提问
我担心我不熟悉使用基线。你有可以分享的任何例子吗?
如果你看克里斯&#39;您提到的代码,您将看到此RenderText
实施:
public override void RenderText(TextRenderInfo renderInfo) {
base.RenderText(renderInfo);
//Get the bounding box for the chunk of text
var bottomLeft = renderInfo.GetDescentLine().GetStartPoint();
var topRight = renderInfo.GetAscentLine().GetEndPoint();
//Create a rectangle from it
var rect = new iTextSharp.text.Rectangle(
bottomLeft[Vector.I1],
bottomLeft[Vector.I2],
topRight[Vector.I1],
topRight[Vector.I2]
);
//Add this to our main collection
this.myPoints.Add(new RectAndText(rect, renderInfo.GetText()));
}
如您所见,他存储的矩形的左下角位于下降线的起点,而右上角则是上升线的末端。
如果您更换
//Get the bounding box for the chunk of text
var bottomLeft = renderInfo.GetDescentLine().GetStartPoint();
var topRight = renderInfo.GetAscentLine().GetEndPoint();
通过
//Get the bounding box for the chunk of text above the baseline
var bottomLeft = renderInfo.GetBaseline().GetStartPoint();
var topRight = renderInfo.GetAscentLine().GetEndPoint();
你的覆盖代码应该可以正常工作。