如何获取PDF的每个单词的坐标?

时间:2017-09-26 10:22:01

标签: c# pdf itext

对于每个单词,我创建一个LocationTextExtractionStrategy类的对象来获取其坐标,但问题是每次我传递一个单词时它返回pdf中存在的该单词的所有块的坐标。如何获取特定位置或特定行中出现的单词的坐标?

我在某个地方找到了代码

namespace PDFAnnotater
 {
   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
{

    public List<RectAndText> myPoints = new List<RectAndText>();


    public string TextToSearchFor { get; set; }


    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;
    }


    public override void RenderText(TextRenderInfo renderInfo)
    {
        base.RenderText(renderInfo);


        var startPosition = System.Globalization.CultureInfo.CurrentCulture.CompareInfo.IndexOf(renderInfo.GetText(), this.TextToSearchFor, this.CompareOptions);

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


        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]
                                                );


        this.myPoints.Add(new RectAndText(rect, this.TextToSearchFor));
    }
}

}

我从数组中传递单词以检查其坐标。问题是RenderText()方法会为每个块一次又一次地自动调用,并返回pdf中不同位置的单词坐标列表。例如,如果我需要坐标'0',它返回23坐标。我应该在代码中做什么或修改什么来获得单词的确切坐标?

1 个答案:

答案 0 :(得分:3)

你的问题有点令人困惑。

  

如何获取特定位置的单词坐标

在那句话中,你基本上是在说“我怎么能得到我已经知道坐标的东西的坐标?”这是多余的。

我要将您的问题解释为“如果我知道大致的位置,我怎样才能获得单词的坐标?”

我不熟悉C#,但我认为有类似于Java的方法来处理Rectangle对象。

  

矩形#crosss(矩形其他)
  确定此Rectangle和指定的Rectangle是否相交。

  

矩形#包含(矩形其他)
   测试Shape的内部是否完全包含指定的Rectangle2D。

然后代码变得非常简单。

  1. 您使用LocationTextExtractionStrategy来获取所有基于iText的矩形
  2. 将它们转换为原生矩形对象(或编写自己的类)
  3. 为您测试的每个矩形是否给定的搜索区域包含该矩形,仅保留搜索区域内的那些矩形
  4. 如果您想实现第二个用例(如果您知道该行,则获取单词的位置),则有两个选项:

    1. 你知道线的粗略坐标
    2. 您希望在行号
    3. 的情况下使用此功能

      对于选项1:

      • 构建搜索区域。使用页面的边界来了解宽度(因为线可以在整个宽度上延伸),并添加一些边距y) - 坐标(以考虑字体差异,下标和上标等)
      • 现在你有了一个搜索区域,这将恢复到我之前的答案。

      对于选项2:

      • 您已经拥有每个单词的y坐标
      • 围绕那些(到最接近的fontsize的倍数)
      • 构建一个地图,用于跟踪某个y坐标的使用次数
      • 删除任何统计异常值
      • 将所有这些值放入List
      • 对列表进行排序

      这可以让您大致了解您可以预期给定行(编号)的位置。

      当然,与我之前的解释类似,你需要考虑一些填充和一定程度的灵活性来得到正确的答案。