65.9K
CodeProject 正在变化。 阅读更多。
Home

创建结构化的表单处理 Web 服务

emptyStarIconemptyStarIconemptyStarIconemptyStarIconemptyStarIcon

0/5 (0投票)

2011 年 6 月 1 日

CPOL

22分钟阅读

viewsIcon

20484

传统的表单处理解决方案在桌面或本地服务器上运行。本白皮书提出了一种替代方法:通过 Web 服务进行表单处理。这允许通过浏览器处理表单、移动表单处理,以及从 .NET 以外的环境访问表单处理

执行摘要

如今,每个人都在关注云计算中的电子数据捕获。然而,纸质表单仍然存在于世界各地的办公室中,管理这些纸质表单是一项挑战。表单处理软件将纸质表单转换为可用的电子数据。传统的表单处理解决方案要么在桌面运行,要么在本地服务器运行。本白皮书提出了一种替代方法:通过 Web 服务进行表单处理。这允许通过浏览器处理表单、移动表单处理,以及从 .NET 以外的环境(如 Java 或 PHP)访问表单处理。通过 Web 服务,您可以在更多平台上为更多应用程序提供表单处理功能。随着文档捕获市场从批量捕获转向即时捕获(在工作站或移动设备上),在更多平台上提供表单处理的能力变得越来越有价值。

结构化表单处理是根据预定义的模板图像和字段分析和提取文档中的数据。典型的结构化表单处理工作流接收一个已填写的表单文档图像,并将其识别为一组已知模板中的一个。一旦找到匹配的模板,就会从表单中提取数据。提取的数据现在可以以有利于将来使用的格式(例如在数据库或 XML 文件中)进行持久化。

概述

本白皮书将指导您使用 Windows Communication Foundation (WCF) 和 Accusoft Pegasus 的 FormSuite 开发结构化表单处理 Web 服务。FormSuite SDK 提供了用于执行结构化表单处理的 .NET 库。这些库包括用于执行图像识别、图像清理和数据提取的功能。数据提取机制包括光学字符识别 (OCR)、手写识别 (ICR)、光学标记识别 (OMR)、条形码识别[1]1 等2。

本文提出的解决方案包含三个部分。第一部分是通过 HTTP 请求公开的表单处理 Web 服务。Web 服务的表单处理能力称为“识别”:它将接受一个已填写的表单图像,并根据一组已知的候选模板进行识别。表单识别是完整表单处理系统的第一步。

第二部分是一个简单的 WinForms 应用程序,它使用 Web 服务。但是,您不一定非要使用 WinForms 或 .NET 来构建您的应用程序;您也可以在 Java 或 PHP 中轻松开发客户端。

最后,本文将说明如何构建表单集,Web 服务将使用该表单集进行识别。

除了将表单处理功能限制为仅表单识别之外,本 Web 服务的开发还采用了许多捷径。最终产品将具有功能,但仅作为开发企业级解决方案的起点。

要求和假设

本白皮书假设读者熟悉 .NET 和 C# 编程语言。本文使用 Visual Studio 2010、.NET 4.0 和 FormSuite version 3 软件开发工具包,可从 www.accusoft.com 获取。

创建 Web 服务

本节将引导您完成使用 WCF 和 FormSuite 构建表单识别 Web 服务的过程。创建的 Web 服务将公开一个可通过 HTTP 请求调用的 API,允许用户将文档图像传递给 Web 服务并检索包含识别结果的 XML 字符串。

架构

Web 服务将构建在两个程序集中。第一个程序集实现并托管 Web 服务 API。第二个程序集实现表单识别功能。这种架构将概念分离,并促进了表单识别代码在其他解决方案中的重用。

Web 服务程序集从控制台应用程序托管 Web 服务。WCF 允许从 IIS 或任何 .NET 应用程序托管 Web 服务。此解决方案选择在控制台应用程序中托管 Web 服务是为了简化实现。我们将从磁盘文件加载表单集信息(如下所述),并在控制台应用程序中托管,而不是在 IIS 中托管,以避免 IIS 特定的配置和权限问题。

该解决方案会将表单集信息持久化到磁盘文件。这使我们无需添加对从数据库读取的支持即可使用 FormDirector。如果本文的范围更大,我们可以选择将表单集信息存储在关系数据库中。

构建 Web 服务 API

首先运行 Visual Studio 2010。创建一个新的控制台应用程序项目,目标框架为 .NET Framework 4。将项目命名为 FormsWebServiceHost,并将解决方案命名为“FormWebService”——因为我们将向解决方案添加其他项目。

您的解决方案资源管理器现在将有一个项目“FormsWebServiceHost”,其中包含一个源代码文件 Program.cs。暂时保持 Program.cs 不变;我们稍后在构建 Web 服务的接口后会再回到这里。

接下来,将 FormsWebServiceHost 项目的目标框架更新为“.NET Framework 4”(默认目标是“.NET Framework 4 Client Profile”)。这是引用 System.ServiceModel.Web 程序集所必需的。

现在我们将构建 Web 服务的接口。为此,我们需要引用程序集 System.ServiceModel.dllSystem.ServiceModel.Web.dll。这些程序集公开了 ServiceContractAttributeOperationContractAttributeWebInvokeAttribute 类,这些类将应用于接口以指定 Web 服务的契约和调用方法。

现在,向项目添加一个新的接口定义代码文件;我们将其命名为“IFormWebService”。

为了指定刚刚创建的接口定义了服务契约,请使用 ServiceContractAttribute(来自 System.ServiceModel 命名空间)标记该接口,如下所示。

    [ServiceContract]
    interface IFormWebService

既然您有了一个定义服务契约的接口,您就需要向服务契约添加一些操作。如前所述,我们的服务将执行表单识别——根据一组已知模板图像识别图像。

我们将在接口中定义一个执行识别的操作。该操作必须接受图像作为输入并返回识别结果。识别结果是复杂的,将包括与输入表单匹配的模板的标识符、识别正确的置信度以及识别失败场景的错误消息。Web 服务将返回 XML,以便任何调用客户端都可以轻松解析这个复杂的结果。

IFormWebService 接口添加一个名为“Identify”的方法。此方法将接受一个 Stream 作为其唯一参数并返回一个“IdentificationInfo”对象。Stream 将包含图像文件。IdentificationInfo 是一个我们将在后面的“构建表单识别程序集”一节中定义的类。另请注意,返回一个类似乎与我们返回 XML 的要求相矛盾,但 WCF 将处理 IdentificationInfo 对象到 XML 的序列化。稍后,我们将介绍为了促进这种序列化,我们需要对 IdentificationInfo 类做些什么。

WebInvokeAttribute 也需要应用于 Identify 方法。这将允许我们指定操作的 URL(相对于 Web 服务的基 URL)以及操作响应的 HTTP 方法(即 GET、POST 等)。我们将使用 POST 操作,因为我们正在发送二进制数据。尽管 POST 是默认操作,但我们将明确指定它以提高可读性。

Identify 方法的声明应如下所示。

    [OperationContract, WebInvoke(UriTemplate = "Identify/", Method = "POST")]
    IdentificationInfo Identify(System.IO.Stream imageStream);

UriTemplate 值表示 Identify 操作可通过 baseURI/Identify/ 访问。

构建 Web 服务的下一步是创建我们的 IFormWebService 接口的具体实现。向项目添加一个新的类定义,并将该类命名为“FormWebService”。

修改此类的实现 IFormWebService。您只需实现 Identify 方法,并且实现应该相当简单,因为它将所有工作委托给 FormsProcessing 程序集中的类。您所需要做的就是添加标准参数检查,并将图像 Stream 传递给 ProcessorManagerIdentifyMethod

FormWebService 类的整个实现应如下所示。

class FormWebService : IFormWebService
{
    public IdentificationInfo Identify(System.IO.Stream imageStream)
    {
        if (imageStream == null)
            throw new ArgumentNullException("imageStream");

        return ProcessorManager.Identify(imageStream);
    }
}

为 Web API 创建主机

现在我们已经定义了 Web 服务,我们需要托管它。这使我们回到 Program.cs 中的 Main 方法。在此方法中,我们将配置并打开一个 System.ServiceModel.ServiceHost 来公开我们的 Web 服务。首先,在 Program.cs 中添加 System.ServiceModelSystem.ServiceModel.Description 命名空间的 using 语句。然后,在 main 方法的主体中,创建 ServiceHost 类的一个实例,指定服务 URI 和实现服务契约的对象的类型。

string serviceUri = "https://:8733/FormProcessing/";
ServiceHost host =
    new ServiceHost(typeof(FormWebService),
                    new Uri(serviceUri));

此时,ServiceHost 没有任何端点;我们必须添加一个端点,以便客户端可以与服务通信。创建端点的第一步是创建一个绑定对象来指定端点的通信协议。由于我们希望服务通过 HTTP 协议通信,因此我们将创建一个 WebHttpBinding

    WebHttpBinding binding = new WebHttpBinding();

由于我们计划将图像传递给服务,因此请增加最大支持文件大小和缓冲区大小。以下代码显示了如何将这些值增加到 128 KB,但您可能希望更高。

    binding.MaxReceivedMessageSize = 131072; // 128 x 1024
    binding.MaxBufferSize = 131072;

接下来我们将创建 ServiceEndpoint 对象,指定端点的契约和绑定。

    ServiceEndpoint serviceEndpoint = 
	host.AddServiceEndpoint("FormsWebServiceHost.IFormWebService", binding, "");

创建服务主机的最后一步是将 WebHttpBehavior 附加到端点;在使用 WebHttpBinding 时,这是必需的。

   WebHttpBehavior behavior = new WebHttpBehavior();
   serviceEndpoint.Behaviors.Add(behavior);

现在服务主机已配置,添加代码以打开服务并使其接受传入请求。命令行应用程序的主线程可以继续执行其他操作,只要您不处置或关闭 ServiceHost 即可。我们将等待按下某个键,以便我们可以优雅地退出服务。并且还要记住将主线程包装在 try-finally 块中,以确保如果发生异常,ServiceHost 能够正确关闭。

try
{
    host.Open();
    Console.ReadLine();
}
finally
{
    host.Close();
}

另一个需要注意的警告是,非管理员帐户默认情况下无权将服务注册到 HTTP 命名空间。这意味着您要么需要以管理员身份运行程序,要么授予运行主机的用户帐户注册到命名空间的权限;有关更多信息,请参阅 http://msdn.microsoft.com/en-us/library/ms733768.aspx

为了使控制台应用程序在启动时请求管理员权限,请向项目添加一个应用程序清单文件。打开该文件,并将 requestedExecutionLevel 元素上的 level 属性从“asInvoker”更改为“requireAdministrator”。

<requestedExecutionLevel 
level="requireAdministrator" uiAccess="false" />

构建表单识别程序集

本节将引导您完成创建执行图像识别的程序集。

首先,向 FormsWebService 解决方案添加一个新的类库项目。将此项目命名为“FormsProcessing”,因为我们将在此处使用 FormSuite 中的组件实现表单处理功能。与之前的程序集一样,此项目的目标框架应该是 .NET Framework 4。

删除 Visual Studio 为您自动生成的类(可能名为“Class1.cs”)。

我们将在此程序集中添加三个类:一个定义我们的结果对象 (IdentificationInfo.cs),一个实现表单处理 (FormsProcessor.cs),以及一个管理对 FormsProcessors 的多线程访问 (ProcessorManager.cs)。

IdentificationInfo

我们将从创建 IdentificationInfo.cs 开始,因为我们已经在前面的部分中讨论过它。这个类存储有关识别结果的信息,这些信息将从这个程序集中的方法返回,而不是从 Accusoft 的 FormFix 组件返回结果对象。我们这样做是因为我们希望封装表单处理的实现细节,并且这还允许我们将 DataContractAttributeDataMemberAttribute(来自 System.Runtime.Serialization 命名空间)应用于 IdentificationInfo 对象及其属性。这些属性指定该类和成员表示一个数据契约(可以独立于此实现定义)并且可以通过 DataContractSerializer 进行序列化。因此,当我们之前说我们的服务契约返回一个 IdentificationInfo 对象时,WCF 会自动(使用数据契约)将 IdentificationInfo 对象序列化为 XML,以便我们的 Web 服务返回一个 XML 字符串。

IdentificationInfo 类的实现应如下所示。

[DataContract]
public class IdentificationInfo
{
    public IdentificationInfo(
Accusoft.FormFixSdk.IdentificationResult identificationResult) {...}

    public IdentificationInfo(Exception e) {...}

    [DataMember]
    public String Name { get; set; }

    [DataMember]
    public int IdentificationConfidence { get; set; }

    [DataMember]
    public String Error { get; set; }
}

为了节省本文档的空间,构造函数的实现细节被省略了,但可以在完整的源代码中找到;请参阅本文档的最后一页以获取链接。

FormsProcessor

构建处理程序集的下一步是创建 FormsProcessor 类并实现表单识别。本文将概述此类别,但不会深入探讨此类的实现细节。完整的实现也可以在完整的源代码中找到。

注意:更多关于使用 FormFix 和 FormDirector 实现表单处理的示例代码可以在 FormAssist 源代码以及 FormFix 和 FormDirector 示例中找到。整个 FormSuite 产品,包括 FormAssist、FormFix 和 FormDirector,可以从 Accusoft 网站 www.accusoft.com/formsuite.htm 下载用于评估。

FormsProcessor 类使用 FormDirector 和 FormFix 组件实现表单识别功能。FormDirector 用作 I/O 层来加载表单集并将其存储在内存中,而 FormFix 实现识别处理。尽管这些组件实现了表单识别所需的大部分功能,但 FormsProcessor 类仍需要实现连接 FormDirector 和 FormFix 的管道,并控制 FormDirector 从磁盘加载表单集文件。

FormsProcessor 类的公共成员如下所示。

    public FormProcessor(){...}
        
public IdentificationInfo Identify(Stream unidentifiedImageStream) {...}

FormsProcessor 将配置为从应用程序工作目录中名为 FormSet.frs 的文件加载表单集。本文档稍后将介绍此文件的创建。

注意:此时我们可能应该讨论我们正在创建一个 Web 服务,但是 FormsProcessor 将使用 FormDirector 从磁盘加载表单集文件。开箱即用,FormDirector 不支持从流中加载和保存表单集,也不支持从数据库中加载和保存表单集。FormDirector 中的概念被抽象出来,以便可以通过派生类支持从流或数据库中加载和保存。

此解决方案从磁盘加载文件并在命令行应用程序中托管我们的服务,因此我们无需编写数据层或担心托管 Web 服务的进程的 I/O 权限。您应该评估应用程序对存储和安全的需求,并使用最合适的实现。

ProcessorManager

构建 FormsProcessing 程序集的最后一步是创建 ProcessorManager 类。该类为使用 FormSuite 创建表单处理 Web 服务所带来的架构挑战提供了一个解决方案。该挑战源于 FormFix IdentificationProcessor 对象的最佳实践使用与 Web 服务的典型架构设计之间的矛盾。

FormFix 的 IdentificationProcessor 的最佳实践使用指出,应为表单集创建一次实例,并且在处理未填充图像之间不应处置或重新创建该实例。这种做法减少了创建和配置对象的开销,并且该类的实例将学习输入图像中的模式,从而随着时间的推移提高识别性能。

Web 服务的典型架构设计避免在对 Web 服务的调用之间共享对象。这样做是为了提高可伸缩性并消除防止并发访问对象所需的复杂代码。

在此处提出的解决方案中,我们将以牺牲 Web 服务要求为代价来瞄准 FormFix 的最佳实践使用。与本文档中提出的所有解决方案一样,您应该评估最适合您的应用程序的解决方案。

ProcessorManager 将是一个静态类,带有一个 FormsProcessor 对象的队列,并且它将有一个名为“Identify”的静态方法,该方法接受一个 Stream 参数。Identify 方法将由 FormWebService 对象调用;对于 Identify 方法的每次调用,一个 FormsProcessor 将从队列中出队,用于执行处理,然后入队。这种机制将确保 FormsProcessor 在同一时间只被一个 Web 服务调用使用。如果对 Web 服务进行多个并发调用,那么其中一个线程可能会发现队列为空,它将不得不等待直到其他线程之一完成使用 FormsProcessor 对象。

我们将使用 ConcurrentQueue<T> 类型(来自 System.Collections.Concurrent 命名空间)作为集合,这样我们就不必管理对 FormsProcessor 的访问同步。在 ProcessorManager 的静态构造函数中,我们将创建与机器上处理器数量一样多的 FormsProcessor。这将允许对 Web 服务进行尽可能多的并发调用,而无需其中一个调用等待。

ProcessorManager 类的构造函数如下所示。

static Processor()
{
    processors = new ConcurrentQueue<FormsProcessor>();

    int numberOfProcessors = System.Environment.ProcessorCount;
    for (int num = 0; num < numberOfProcessors; num++)
    {
        processors.Enqueue(new FormsProcessor());
    }
}

并且,ProcessorManager 类的 Identify 方法如下所示。

public static IdentificationInfo Identify(Stream unidentifiedImageStream)
{
    FormsProcessor formProcessor;
    while (!processors.TryDequeue(out formProcessor))
    {
        System.Threading.Thread.Sleep(100);
    }
    
    try
    {
        return formProcessor.Identify(unidentifiedImageStream);
    }
    catch (Exception e)
    {
        return new IdentificationInfo(e);
    }
    finally
    {
        processors.Enqueue(formProcessor);
    }
}

现在,我们已经完成了 FormsProcessing 程序集的开发,应该更新 FormsWebServiceHost 项目以引用 FormsProcessing 程序集。然后可以将 FormsProcessing 命名空间的 using 语句添加到 IFormWebService.csFormWebService.cs 文件中。

现在一切都应该可以构建了。您可以运行控制台应用程序来启动 Web 服务,但是当进行 API 调用时它会失败,因为我们还没有为它创建表单集。在接下来的两节中,我们将创建一个客户端应用程序来测试 Web 服务,并演示如何使用 FormAssist 创建表单集。

创建测试客户端

在本节中,我们将为 Web 服务创建一个测试客户端。客户端将是一个简单的 WinForms 应用程序,带有一个按钮,用于打开对话框以选择图像;然后图像将发送到 Web 服务。客户端还将有一个文本框来显示从 Web 服务接收到的 XML。

要构建客户端,首先向 FormsWebService 解决方案添加一个新的 Windows Forms 应用程序项目。同样,目标框架应为 .NET Framework 4。

您现在应该有一个新项目,其中包含一个名为 Form1 的空窗体。向 Form1 添加一个 Button 和 TextBox。通过将其 Multiline 属性设置为 true,使 TextBox 成为多行,然后将 TextBox 的名称更改为“resultsTextBox”。

现在,为按钮的 Click 事件添加一个事件处理程序。在此事件处理程序中,我们将向用户显示一个文件打开对话框,以选择要识别的图像文件。

OpenFileDialog openFileDialog = new OpenFileDialog();
if (openFileDialog.ShowDialog() != System.Windows.Forms.DialogResult.OK) return;

然后,我们将尝试打开文件并将其内容读入字节数组。此字节数组将传递给 Web 服务。

byte[] imageBuffer;
using (Stream fileStream = new FileStream(openFileDialog.FileName, FileMode.Open))
{
    imageBuffer = new byte[fileStream.Length];
    fileStream.Read(imageBuffer, 0, imageBuffer.Length);
}

注意:您可以选择使用 ImagXpress 打开图像以验证其是否为受支持的文件类型,然后可以在发送到 Web 服务之前压缩图像。.

注 2:这也是一个很好的地方来验证文件大小是否不超过最大支持文件大小,我们在构建服务时将其设置为 128KB.

下一步是向 Web 服务发出 Web 请求,传递图像字节。这是通过创建 HttpWebRequest 实例(来自 System.Net 命名空间)并指定使用 POST 方法和请求流的内容类型来完成的。我们将内容类型设置为“application/octet-stream”,因为我们正在发送可能是多种图像文件格式之一的二进制数据。然后将请求流的内容设置为 imageBuffer,并关闭请求流。然后我们可以从 Web 请求获取响应,读取文本,并将其写入 resultsTextBox。完成所有这些的代码如下所示。

HttpWebRequest httpWebRequest =
    WebRequest.Create(@"https://:8733/FormProcessing/Identify/")
as HttpWebRequest;
if (httpWebRequest != null)
{
    httpWebRequest.Method = "POST";
    httpWebRequest.ContentType = "application/octet-stream";
    
    Stream requestStream = httpWebRequest.GetRequestStream();
    requestStream.Write(imageBuffer, 0, imageBuffer.Length);
    requestStream.Close();

    String response = String.Empty;

    WebResponse webResponse = httpWebRequest.GetResponse();
    using (StreamReader streamReader = new StreamReader(webResponse.GetResponseStream()))
        response = streamReader.ReadToEnd();

    resultsTextBox.Text = response;
}

现在我们已经完成了 Web 服务和测试客户端的构建。剩下的唯一一步是为 Web 服务创建表单集。这将在下一节中介绍。

创建表单集

我们将使用 FormAssist,即 FormSuite 演示应用程序,来创建 Web 服务将用于识别的表单集。FormAssist 随 FormSuite 版本 3 SDK 一起安装;您可以在“开始”菜单中的“程序”>“Accusoft”>“演示程序”>“FormAssist 3”下找到编译后的演示应用程序。运行演示,我们将构建表单集。

当启动对话框弹出,要求您选择一个选项以开始时,选择“创建新的表单模板库”并按“确定”。

现在 FormAssist 将打开一个空表单集。我们将向表单集添加几个表单(模板图像);这些是将用于识别的模板图像。只支持位图(黑白)图像,因此在添加任何图像之前,请确保它们是位图。您可以使用图像编辑器(如 MS Paint 或 GIMP)转换任何灰度或彩色图像。

要添加表单,请在文件菜单下选择“将新表单添加到表单集…”项。这将打开一个对话框,您可以在其中选择表单的模板图像。FormSuite SDK 在 %public%\Documents\Pegasus Imaging\Common\Images 下安装了一些图像,我们将使用这些图像。

选择图像“BloomingtonPoliceBlank.tif”,然后打开它。这会将一个新表单添加到您的表单集中,其中 BloomingtonPoliceBlank.tif 作为模板图像。表单集树应反映您现在拥有此表单,如下图所示。

此表单的名称已根据模板图像的名称设置,但可以更改为更合适的值。此名称将作为 Web 服务返回的表单标识符值。要更改名称,请在表单集树中选择表单。表单集树下方的设置面板现在将包含表单的设置。选择包含表单名称的文本框(这是您可以编辑的唯一文本框和控件),更新名称,然后按 Enter 键。结果如下图所示。

对于我们只执行表单识别的 Web 服务,您只需执行此操作即可将表单(模板图像)添加到表单集。FormAssist 还有更多功能,可以指定清理操作或定义表单上的字段,但本白皮书中的 FormsProcessing 程序集目前不支持表单处理的任何其他部分;它只进行识别。

现在,为了让事情变得有趣,按照与上述相同的步骤向表单集添加更多表单。从 FormSuite 安装的相同图像文件夹中,添加图像“TexasLotteryBlank.tif”和“RailroadRetirementTaxBlank.tif”。在实际情况中,您可能需要将图像与许多可能的模板进行匹配。

现在我们已经将所有要添加到表单集的表单都添加了,我们需要在 FormAssist 中使用表单集处理一张图像。这使 FormFix 有机会加载表单集并分析表单集中的图像,然后我们可以在保存表单集时将这些信息与表单集一起存储。此步骤不是必需的,但强烈建议;它将加快 Web 服务中的操作。

要处理一张图像,请在工具菜单下选择“处理表单…”项。您可以选择任何二值图像进行处理。这次,选择“%public%\Documents\Pegasus Imaging\Common\Images\RailroadRetirementTaxFilled.tif”。FormAssist 处理表单窗口将出现。处理完成后,请随意探索。探索完成后单击“退出”。

现在我们可以保存表单集了。请记住,在构建 Web 服务时,我们指定 Web 服务将从托管服务的进程工作目录中名为“FormSet.frs”的文件加载表单集。要保存到此位置,请在“文件”菜单下选择“保存表单集”项,然后导航到 FormsWebServiceHost 项目的构建目录。

将文件名更改为“FormSet.frs”,然后单击保存。

就这样!现在您可以运行您的 Web 服务并使用您的测试客户端执行图像识别。

运行测试

要测试识别,首先运行 FormsWebServiceHost.exe。您应该会看到一个空白的控制台窗口。

接下来运行 FormsWebServiceTestClient.exe。这将打开一个窗口,如下图所示。

单击“识别”按钮,然后选择一个二值图像进行识别。像以前一样,对于第一次运行,选择图像“%public%\Documents\Pegasus Imaging\Common\Images\RailroadRetirementTaxFilled.tif”。单击“确定”后,图像将发送到处理服务器。图像应该被处理并返回 XML 结果。XML 显示在对话框中。

如您所见,图像被识别为与模板 RailroadRetirementTaxBlank 匹配,置信度值为 97。

至此,一个用于执行表单识别的 Web 服务已成功实现和测试。

更多源代码

为了提高可读性,表单处理 Web 服务的一些实现部分被省略了;.NET 中源代码的完整副本可以从 Accusoft 网站下载:http://www.accusoft.com/whitepapers/formsuite/FormsWebService.zip

关于 FormSuite

FormSuite 将 Accusoft Pegasus 的所有表单处理组件捆绑到一个方便的安装包中,并在您购买所有包含的组件时提供折扣价格。您可以在此处下载 FormSuite 的全功能无限制试用版:http://www.accusoft.com/formsuitedownload.htm。请通过 info@accusoft.cominfo@accusoft.com 联系我们以获取更多信息。

关于作者

Mark Duckworth,自 2008 年以来的软件工程师,一直负责 Accusoft Pegasus 产品系列中产品的开发工作。他的贡献包括表单处理、OCR、ICR、MICR、TWAIN、Silverlight、Java 等方面的工作。Mark 获得了佐治亚理工学院的计算机科学硕士学位和计算机科学学士学位。

1、2 条形码识别和其他识别引擎不随 FormSuite 提供,但 Accusoft 提供兼容的识别引擎。

© . All rights reserved.