Document scanning on Windows C# with an incremental custom progress UI?

1.8k Views Asked by At

How can I incrementally scan a document on Windows, from C#, while getting callbacks to show pieces of the image as they come in, and update my own custom progress UI?

It looks like the scanner API options include:

  • WIA, WIA Script Automation (windows)
  • TWAIN (windows, linux)
  • ImageKit and ImageCaptureCore (MacOS)
  • SANE (linux)
  • ISIS (windows, expensive commercial).

My attempt on WIA Script Automation:

I have a simple C# application which uses Windows WIA Script Automation to scan a document. (see the code on github) However, during the Scan the UI is hijacked by a popup progress dialog.

The current code scans using the WIA Scripting CommonDialog.showTransfer (see here), which shows a popup progress bar dialog. I understand I can instead use Item.Transfer, however, it blocks for the entire duration and offers no callback so I can update my own custom progress UI (or cancel the transfer).

Is there any way to do a non-blocking scan with WIA, or to get progress callbacks?

Do I have to use TWAIN?

1

There are 1 best solutions below

6
David Jeske On

It looks like there are two options for non-blocking streaming scanning on Windows:

WIA COM

It's important to note that WIA has both a high-level "script automation" interface and a low-level COM interface. Using the low level WIA COM provides a stream based data-transfer method using IWiaTransfer and IWiaTransferCallback.

Unfortunately, the C# WIA wrappers I can find are using the script automation interface, which does not provide a streaming scan interface.

Twain

Page 4-20 of the Twain Specification, titled Buffered Memory Mode Transfer, explains how to use a fixed-size buffer to incrementally transfer the scan data using the commands DAT_SETUPMEMXFER and DAT_IMAGEMEMXFER. This still blocks for each incremental memory buffer, but after each buffer it allows the application to show the partial incoming data, and continue the transfer or cancel it.

I tried twain-cs and twain-dsm as supplied by twain.org, but they don't see my scanner. I'd also like to avoid have to install the LGPL twaindsm.dll.

The twaindotnet wrapper provides some Twain support which works and doesn't require the native TwainDSM DLL. Unfortunately, it doesn't (yet) support Buffered Memory Transfers. Therefore, I extended it.

My incremental_scanning branch of twaindotnet is able to incrementally show the image pixels as they arrive, right in the native UI. However, it still blocks the UI thread for each incremental transfer chunk. It's not clear if this blocking can be moved to a background thread or not.

youtube video of incremental scan progress