使用 iText7 从 PDF 中提取文本。如何提高其性能?

2023-12-10

目前,我使用此代码从矩形(区域)中提取文本。

public static class ReaderExtensions
{
    public static string ExtractText(this PdfPage page, Rectangle rect)
    {
        var filter = new IEventFilter[1];
        filter[0] = new TextRegionEventFilter(rect);
        var filteredTextEventListener = new FilteredTextEventListener(new LocationTextExtractionStrategy(), filter);
        var str = PdfTextExtractor.GetTextFromPage(page, filteredTextEventListener);
        return str;
    }
}

它有效,但我不知道这是否是最好的方法。

另外,我想知道 iText 团队是否可以改进 GetTextFromPage 以提高其性能,因为我正在处理大型 PDF 中的数百个页面,并且使用我当前的配置通常需要 10 多分钟才能完成。

EDIT:

从评论来看:看起来iText可以一次提取同一页面上多个矩形的文本,这可以提高性能(批量操作往往更高效),但是如何呢?

更多细节!

我的目标是从多页 PDF 中提取数据。每个页面都有相同的布局:包含行和列的表格。

目前,我正在使用上面的方法来提取每个矩形的文本。但是,如您所见,提取不是批量的。一次只是一个矩形。如何一次性提取页面的所有矩形?


正如评论中已经提到的,我很惊讶地发现 iText 7LocationTextExtractionStrategy不再包含类似于 iText 5 的内容LocationTextExtractionStrategy method GetResultantText(TextChunkFilter)。这将允许您解析一次页面并从任意页面区域中的文本片段中提取文本。

但有可能恢复该功能。一种选择是将其添加到LocationTextExtractionStrategy。不过,这将是一个很长的答案。所以我使用了另一个选择:我使用现有的LocationTextExtractionStrategy,并且仅仅为了GetResultantText调用我操纵策略的文本块的底层列表。而不是通用的TextChunkFilter界面我将过滤限制为手头的标准,即按矩形区域进行过滤。

public static class ReaderExtensions
{
    public static string[] ExtractText(this PdfPage page, params Rectangle[] rects)
    {
        var textEventListener = new LocationTextExtractionStrategy();
        PdfTextExtractor.GetTextFromPage(page, textEventListener);
        string[] result = new string[rects.Length];
        for (int i = 0; i < result.Length; i++)
        {
            result[i] = textEventListener.GetResultantText(rects[i]);
        }
        return result;
    }

    public static String GetResultantText(this LocationTextExtractionStrategy strategy, Rectangle rect)
    {
        IList<TextChunk> locationalResult = (IList<TextChunk>)locationalResultField.GetValue(strategy);
        List<TextChunk> nonMatching = new List<TextChunk>();
        foreach (TextChunk chunk in locationalResult)
        {
            ITextChunkLocation location = chunk.GetLocation();
            Vector start = location.GetStartLocation();
            Vector end = location.GetEndLocation();
            if (!rect.IntersectsLine(start.Get(Vector.I1), start.Get(Vector.I2), end.Get(Vector.I1), end.Get(Vector.I2)))
            {
                nonMatching.Add(chunk);
            }
        }
        nonMatching.ForEach(c => locationalResult.Remove(c));
        try
        {
            return strategy.GetResultantText();
        }
        finally
        {
            nonMatching.ForEach(c => locationalResult.Add(c));
        }
    }

    static FieldInfo locationalResultField = typeof(LocationTextExtractionStrategy).GetField("locationalResult", BindingFlags.NonPublic | BindingFlags.Instance);
}

中央扩展是LocationTextExtractionStrategy扩展需要一个LocationTextExtractionStrategy它已经包含页面中的信息,将这些信息限制为给定矩形中的信息,提取文本,并将信息返回到先前的状态。这需要一些反思;我希望这对你来说没问题。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用 iText7 从 PDF 中提取文本。如何提高其性能? 的相关文章

  • 为什么两个不同的 Base64 字符串的转换会返回相等的字节数组?

    我想知道为什么从 base64 字符串转换会为不同的字符串返回相同的字节数组 const string s1 dg const string s2 dq byte a1 Convert FromBase64String s1 byte a2
  • 秒表有最长运行时间吗?

    多久可以Stopwatch在 NET 中运行 如果达到该限制 它会回绕到负数还是从 0 重新开始 Stopwatch Elapsed返回一个TimeSpan From MSDN https learn microsoft com en us
  • ASP.NET MVC:这个业务逻辑应该放在哪里?

    我正在开发我的第一个真正的 MVC 应用程序 并尝试遵循一般的 OOP 最佳实践 我正在将控制器中的一些简单业务逻辑重构到我的域模型中 我最近一直在阅读一些内容 很明显我应该将逻辑放在域模型实体类中的某个位置 以避免出现 贫血域模型 反模式
  • Asp.NET WebApi 中类似文件名称的路由

    是否可以在 ASP NET Web API 路由配置中添加一条路由 以允许处理看起来有点像文件名的 URL 我尝试添加以下条目WebApiConfig Register 但这不起作用 使用 URIapi foo 0de7ebfa 3a55
  • Clang 3.1 + libc++ 编译错误

    我已经构建并安装了 在前缀下 alt LLVM Clang trunk 2012 年 4 月 23 日 在 Ubuntu 12 04 上成功使用 GCC 4 6 然后使用此 Clang 构建的 libc 当我想使用它时我必须同时提供 lc
  • 使用 WebClient 时出现 System.Net.WebException:无法创建 SSL/TLS 安全通道

    当我执行以下代码时 System Net ServicePointManager ServerCertificateValidationCallback sender certificate chain errors gt return t
  • C++ OpenSSL 导出私钥

    到目前为止 我成功地使用了 SSL 但遇到了令人困惑的障碍 我生成了 RSA 密钥对 之前使用 PEM write bio RSAPrivateKey 来导出它们 然而 手册页声称该格式已经过时 实际上它看起来与通常的 PEM 格式不同 相
  • 带动态元素的 WPF 启动屏幕。如何?

    我是 WPF 新手 我需要一些帮助 我有一个加载缓慢的 WPF 应用程序 因此我显示启动屏幕作为权宜之计 但是 我希望能够在每次运行时更改屏幕 并在文本区域中显示不同的引言 这是一个生产力应用程序 所以我将使用非愚蠢但激励性的引言 当然 如
  • 创建链表而不将节点声明为指针

    我已经在谷歌和一些教科书上搜索了很长一段时间 我似乎无法理解为什么在构建链表时 节点需要是指针 例如 如果我有一个节点定义为 typedef struct Node int value struct Node next Node 为什么为了
  • 转发声明和包含

    在使用库时 无论是我自己的还是外部的 都有很多带有前向声明的类 根据情况 相同的类也包含在内 当我使用某个类时 我需要知道该类使用的某些对象是前向声明的还是 include d 原因是我想知道是否应该包含两个标题还是只包含一个标题 现在我知
  • 如何在 C 中调用采用匿名结构的函数?

    如何在 C 中调用采用匿名结构的函数 比如这个函数 void func struct int x p printf i n p x 当提供原型的函数声明在范围内时 调用该函数的参数必须具有与原型中声明的类型兼容的类型 其中 兼容 具有标准定
  • 使用 x509 证书签署 json 文档或字符串

    如何使用 x509 证书签署 json 文档或字符串 public static void fund string filePath C Users VIKAS Desktop Data xml Read the file XmlDocum
  • 覆盖子类中的字段或属性

    我有一个抽象基类 我想声明一个字段或属性 该字段或属性在从该父类继承的每个类中具有不同的值 我想在基类中定义它 以便我可以在基类方法中引用它 例如覆盖 ToString 来表示 此对象的类型为 property field 我有三种方法可以
  • 对现有视频添加水印

    我正在寻找一种用 C 在视频上加水印的方法 就像在上面写文字一样 图片或文字标签 我该怎么做 谢谢 您可以使用 Nreco 视频转换器 代码看起来像 NReco VideoConverter FFMpegConverter wrap new
  • USB 上的 Autorun.inf 可以让它运行 pdf 吗?

    我在网上做了一些研究 我想我只是在寻找构象 由于 Microsoft 如何在 Vista 及更高版本中对自动运行设置安全性 从 USB 自动运行不再起作用 正确的 看起来它仍然会显示运行 exe 的选项 但由于某些奇怪的原因我无法让它运行
  • WPF/C# 将自定义对象列表数据绑定到列表框?

    我在将自定义对象列表的数据绑定到ListBox in WPF 这是自定义对象 public class FileItem public string Name get set public string Path get set 这是列表
  • 基于 OpenCV 边缘的物体检测 C++

    我有一个应用程序 我必须检测场景中某些项目的存在 这些项目可以旋转并稍微缩放 更大或更小 我尝试过使用关键点检测器 但它们不够快且不够准确 因此 我决定首先使用 Canny 或更快的边缘检测算法 检测模板和搜索区域中的边缘 然后匹配边缘以查
  • IEnumreable 动态和 lambda

    我想在 a 上使用 lambda 表达式IEnumerable
  • C++ 中类级 new 删除运算符的线程安全

    我在我的一门课程中重新实现了新 删除运算符 现在我正在使我的代码成为多线程 并想了解这些运算符是否也需要线程安全 我在某处读到 Visual Studio 中默认的 new delete 运算符是线程安全的 但这对于我的类的自定义 new
  • 使用.NET技术录制屏幕视频[关闭]

    Closed 这个问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 有没有一种方法可以使用 NET 技术来录制屏幕 无论是桌面还是窗口 我的目标是免费的 我喜欢小型 低

随机推荐