如何异步扫描和传输文档进纸器中的图像

时间:2010-12-15 18:10:43

标签: .net backgroundworker hwnd twain

与TWAIN通信的哪些部分可以放入另一个线程,例如一个BackgroundWorker? 要么: 是否可以拆分处理图像传输的循环?

某些扫描仪驱动程序会在返回调用应用程序之前扫描所有图像,这会强制应用程序立即处理所有图像。这导致例如OutOfMemory异常或我的WPF应用程序中的奇怪行为,当突然所有事件(在每个扫描图像之后引发)必须立即处理。此外,应用程序会挂起,直到传输完成。

我正在使用TwainDotNet:http://code.google.com/p/twaindotnet/但我也在寻找一个通用的解决方案来描述消息过滤器以及与TWAIN独立的TwainDotNet的交互。包含TWAIN消息的工作流程就足够了。其他语言也是受欢迎的,比较喜欢C或Deplhi。

DataSourceManager中消息过滤器的当前实现可以描述如下:

  • 从窗口句柄(hwnd)获取消息信息
  • 复制过滤器,将内容发送到TWAIN等。
  • 如果消息关闭(例如,在TWAIN UI中按取消按钮时)
    • 关闭数据源
    • 停用过滤器
    • 调用ScanningComplete事件
  • 如果邮件传输准备就绪:
    • 在循环中(直到ADF为空等,这会阻止消息过滤器)
      • 获取图片
      • 将图像指针转换为GDI +图像
      • 以图像作为参数
      • 调用TransferImage事件
    • 重置转移
    • 关闭数据源等(与消息关闭相同)
  • 通知窗口,已处理邮件

我用几台扫描仪对此进行了测试:

  • 每次传输页面时,Fujitsu fi-5120C都会调用TransferImage事件。该图像会立即弹出我的WPF应用程序中的图像列表。
  • 佳能DR-5010C会阻止我的WPF应用程序,直到扫描完所有图像(直到循环结束)。 Windows甚至说,WPF应用程序没有响应。传输完所有图像后,只显示少量图像,图像列表中的选择闪烁等。

我不关心显示问题,而是关注被阻止的窗口和内存问题。将将图像传输到BackgroundWorker的循环导致几次崩溃,我无法调试。因为我考虑了WPF的线程问题。 我也不知道如何拆分传输循环,这样,在传输一个图像后,程序返回到消息过滤器,消息可以标记为已处理。

1 个答案:

答案 0 :(得分:8)

我为Atalasoft工作,但我不了解WPF,甚至不了解DotTwain!

我可以告诉你,通常TWAIN扫描可以在一个单独的扫描线程上完成,但你必须要小心。最简单的方法是在扫描线程上执行所有TWAIN操作 - 不要在两个线程之间混合TWAIN调用。

扫描线程必须有消息泵或者是' UI'线程,无论你的环境如何。它不仅仅是一个工人线程。

TWAIN希望获得一个窗口句柄(老式的Win32 HWND),用作扫描程序用户界面的父窗口。我建议您创建一个扫描父母'用于此目的的窗口,在扫描线程上。您可以根据需要选择它,也可以在扫描作业结束时将其销毁。

如果扫描作业非常大(例如50页400 DPI颜色),则必须确保扫描过程不会填满逻辑内存或RAM。如果填满逻辑内存(32位Windows进程可以获得大约2GB的地址空间)分配将失败。如果填满RAM,消耗/处理传入图像的代码可能会开始交换,从根本上减慢速度,然后扫描向前运行并填满逻辑内存。所以你需要:

  1. 在扫描中完全处理和处理每个传入的图像 线程,或
  2. 限制扫描线程中的图像流量 在处理/处置之前不能跑得太远。
  3. 我经常发现我希望能够取消扫描线程,这需要一些耐心,因为TWAIN调用不能被中断,而且其中一些很重。你已经注意到你的佳能。另一方面,如果强制终止TWAIN调用中的线程,扫描程序可能需要重启或甚至系统重启,TWAIN本身将阻塞,直到TWAIN管理器DLL从内存中卸载并重新加载。通常最好礼貌地关闭TWAIN。