iTextSharp-覆盖文本
本文关键字:文本 覆盖 iTextSharp- | 更新日期: 2023-09-27 18:27:15
在下面的代码中,我试图在现有文本上放置一层文本(通过用白色字体书写原始现有文本,将其"隐藏";它用作此替换过程的占位符)。下面的代码在很大程度上依赖于Chris Haas在这篇文章中提供的代码:
Itextsharp 中使用ITextExtractionStrategy和LocationTextExtractionStrategie获取字符串坐标
然而,我的文本位置的"左"位置很好,但"底部"低于我试图覆盖的文本(即使字体相同)。如何更改此项以获得原始文档中文本的正确坐标?原始文档是使用表格进行布局创建的,所以这会影响"覆盖"过程吗?
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();
}
Chris’MyLocationTextExtractionStrategy
只考虑文本片段的下降线和上升线,因为它对字符串使用的区域感兴趣。
不过,对于您的任务,您需要基线,因为文本绘制操作使用当前位置作为基线起点。
因此,您应该创建Chris类的一个变体,它管理文本的基线,而不是/除了它的上升和下降线。
PS:OP在评论中询问
恐怕我不熟悉使用基线。你有什么可以分享的例子吗?
如果你看看你提到的Chris的代码,你会看到这个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();
重写代码应该可以正常工作。