gpt4 book ai didi

c# - 在 Itextsharp 中使用 ITextExtractionStrategy 和 LocationTextExtractionStrategy 获取字符串坐标

转载 作者:行者123 更新时间:2023-12-04 09:57:16 33 4
gpt4 key购买 nike

我有一个 PDF 文件,我正在使用 ITextExtractionStrategy 将其读入字符串。现在我从字符串中获取一个子字符串,例如 My name is XYZ 并且需要从 PDF 中获取子字符串的直角坐标文件,但无法执行。在谷歌搜索中,我知道了 LocationTextExtractionStrategy 但不知道如何使用它来获取坐标。

这是代码..

ITextExtractionStrategy strategy = new SimpleTextExtractionStrategy();
string currentText = PdfTextExtractor.GetTextFromPage(pdfReader, page, strategy);
currentText = Encoding.UTF8.GetString(ASCIIEncoding.Convert(Encoding.Default, Encoding.UTF8, Encoding.Default.GetBytes(currentText)));
text.Append(currentText);

string getcoordinate="My name is XYZ";

如何使用 ITEXTSHARP 获取此子字符串的直角坐标..

请帮忙。

最佳答案

这是一个非常非常简单的实现版本。

在实现它之前非常要知道 PDF 对“单词”、“段落”、“句子”等的概念为零。此外,文本中的文本PDF 不一定从左到右和从上到下排列,这与非 LTR 语言无关。短语“Hello World”可以这样写到 PDF 中:

Draw H at (10, 10)
Draw ell at (20, 10)
Draw rld at (90, 10)
Draw o Wo at (50, 20)

也可以写成

Draw Hello World at (10,10)

您需要实现的 ITextExtractionStrategy 接口(interface)有一个名为 RenderText 的方法,它会为 PDF 中的每个文本 block 调用一次。注意我说的是“ block ”而不是“词”。在上面的第一个示例中,该方法将针对这两个词调用四次。在第二个例子中,它会为这两个词调用一次。这是理解的非常重要的部分。 PDF 没有文字,因此 iTextSharp 也没有文字。 “单词”部分 100% 由您来解决。

此外,正如我上面所说,PDF 没有段落。需要注意这一点的原因是 PDF 无法将文本换行。每当您看到看起来像段落返回的内容时,您实际上看到的是一个全新的文本绘制命令,它具有与上一行不同的 y 坐标。参见 this for further discussion .

下面的代码是一个非常简单的实现。为此,我将 LocationTextExtractionStrategy 子类化,它已经实现了 ITextExtractionStrategy。在每次调用 RenderText() 时,我都会找到当前 block 的矩形(使用 Mark's code here )并将其存储以备后用。我正在使用这个简单的辅助类来存储这些 block 和矩形:

//Helper class that stores our rectangle and text
public class RectAndText {
public iTextSharp.text.Rectangle Rect;
public String Text;
public RectAndText(iTextSharp.text.Rectangle rect, String text) {
this.Rect = rect;
this.Text = text;
}
}

这是子类:

public class MyLocationTextExtractionStrategy : LocationTextExtractionStrategy {
//Hold each coordinate
public List<RectAndText> myPoints = new List<RectAndText>();

//Automatically called for each chunk of text in the PDF
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()));
}
}

最后是上面的实现:

//Our test file
var testFile = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Desktop), "test.pdf");

//Create our test file, nothing special
using (var fs = new FileStream(testFile, FileMode.Create, FileAccess.Write, FileShare.None)) {
using (var doc = new Document()) {
using (var writer = PdfWriter.GetInstance(doc, fs)) {
doc.Open();

doc.Add(new Paragraph("This is my sample file"));

doc.Close();
}
}
}

//Create an instance of our strategy
var t = new MyLocationTextExtractionStrategy();

//Parse page 1 of the document above
using (var r = new PdfReader(testFile)) {
var ex = PdfTextExtractor.GetTextFromPage(r, 1, t);
}

//Loop through each chunk found
foreach (var p in t.myPoints) {
Console.WriteLine(string.Format("Found text {0} at {1}x{2}", p.Text, p.Rect.Left, p.Rect.Bottom));
}

我怎么强调都不为过,上面的没有考虑“单词”,这将取决于您。传递给 RenderTextTextRenderInfo 对象有一个名为 GetCharacterRenderInfos() 的方法,您可以使用它来获取更多信息。如果您不关心字体中的下部,您可能还想使用 GetBaseline() 而不是 GetDescentLine()`。

编辑

(我吃了一顿丰盛的午餐,所以我感觉更有帮助了。)

这是 MyLocationTextExtractionStrategy 的更新版本,它执行我在下面的评论中所说的,即它需要一个字符串来搜索并在每个 block 中搜索该字符串。由于列出的所有原因,这在某些/许多/大多数/所有情况下都不起作用。如果子字符串在单个 block 中多次存在,它也将只返回第一个实例。连字和变音符号也可能与此混淆。

public class MyLocationTextExtractionStrategy : LocationTextExtractionStrategy {
//Hold each coordinate
public List<RectAndText> myPoints = new List<RectAndText>();

//The string that we're searching for
public String TextToSearchFor { get; set; }

//How to compare strings
public System.Globalization.CompareOptions CompareOptions { get; set; }

public MyLocationTextExtractionStrategy(String textToSearchFor, System.Globalization.CompareOptions compareOptions = System.Globalization.CompareOptions.None) {
this.TextToSearchFor = textToSearchFor;
this.CompareOptions = compareOptions;
}

//Automatically called for each chunk of text in the PDF
public override void RenderText(TextRenderInfo renderInfo) {
base.RenderText(renderInfo);

//See if the current chunk contains the text
var startPosition = System.Globalization.CultureInfo.CurrentCulture.CompareInfo.IndexOf(renderInfo.GetText(), this.TextToSearchFor, this.CompareOptions);

//If not found bail
if (startPosition < 0) {
return;
}

//Grab the individual characters
var chars = renderInfo.GetCharacterRenderInfos().Skip(startPosition).Take(this.TextToSearchFor.Length).ToList();

//Grab the first and last character
var firstChar = chars.First();
var lastChar = chars.Last();


//Get the bounding box for the chunk of text
var bottomLeft = firstChar.GetDescentLine().GetStartPoint();
var topRight = lastChar.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, this.TextToSearchFor));
}

您可以像以前一样使用它,但现在构造函数只有一个必需参数:

var t = new MyLocationTextExtractionStrategy("sample");

关于c# - 在 Itextsharp 中使用 ITextExtractionStrategy 和 LocationTextExtractionStrategy 获取字符串坐标,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44405214/

33 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com