Twain question: is it possible to scan just one do

2020-02-08 06:50发布

问题:

I am playing with the code from http://www.codeproject.com/KB/dotnet/twaindotnet.aspx

I am having a problem because twain returns control only after all documents in feeder are scanned. This leads to high memory usage if I scan 20 or more documents.

I thought of scanning just one document at a time from the feeder and saving the image and calling the api again in a loop.

I am setting cap_xfercount to 1 but this does not seem to help:

    TwCapability cap = new TwCapability(TwCap.XferCount, 1);
    rc = DScap(appid, srcds, TwDG.Control, TwDAT.Capability, TwMSG.Set, cap);

What do I need to do to scan just one document from the feeder? Any suggestions appreciated.

回答1:

I'm sorry that I'm not familiar with the twaindotnet project, but I do have a lot of experience with document scanning through TWAIN.

First a note: Not all document feeders can feed in single-page mode; some important scanner families always scan everything in the feeder once started. And, quite a few TWAIN drivers won't honor XFERCOUNT=1, no matter what the standard says.

If you try to solve the problem by forcing the scanner to scan "one page jobs", you will be limited to the (indeterminate) set of scanners that happen to support that. The TWAIN standard just doesn't require this feature. (But yes - CAP_AUTOSCAN=FALSE and XFERCOUNT=1 would be the combo to try.)

There is a better solution (time & patience permitting) - It sounds like what you want to do is process and dispose of each image as it arrives, instead of collecting them all in memory. Figure out how to get your TWAIN library to hand you each image (or write it to a file) as it arrives instead of stacking them up in memory, and you'll have a solution that works with all document-feeding scanners. And it will scan quite a bit faster with most scanners, too...



回答2:

This is a feeder issue. Have you tried setting the feeder enabled capability to false?

EDIT:

Looks like CAP_AUTOFEED is the way to go. According to the TWAIN 2.0 specification:

CAP_AUTOFEED Description If TRUE, the Source will automatically feed the next page from the document feeder after the number of frames negotiated for capture from each page are acquired. CAP_FEEDERENABLED must be TRUE to use this capability. Application Set the capability to TRUE to enable the Source’s automatic feed process, or FALSE to disable it. After the completion of each transfer, check TW_PENDINGXFERS. Count to determine if the Source has more images to transfer. A -1 means there are more images to transfer but the exact number is not known. CAP_FEEDERLOADED indicates whether the Source’s feeder is loaded. (The automatic feed process continues whenever this capability is TRUE.)



回答3:

The order of the cababilities is important, see this doc www.twain.org/docs/CapOrderForWeb.

EDIT:

These are some code fragments from a solution

Setup the auto feed

capFeederEnabled = _twEntities.GetCapability(TwCap.FeederEnabled, (short)1);
TwRC rc = DScap(_applicationId, _sourceId, TwDG.Control, TwDAT.Capability, TwMSG.Set, capFeederEnabled);

TwCapability cap = _twEntities.GetCapability(TwCap.XferCount, 1);
rc = DScap(_applicationId, _sourceId, TwDG.Control, TwDAT.Capability, TwMSG.Set, cap);

and then when the when the Twain Window Message is sent

rc = DSixfer(_applicationId, _sourceId, TwDG.Image, TwDAT.ImageNativeXfer, TwMSG.Get, ref hbitmap);
rc = DSpxfer(_applicationId, _sourceId, TwDG.Control, TwDAT.PendingXfers, TwMSG.EndXfer, pxfr);

finally reset the scanner for the next document

rc = DSpxfer(_applicationId, _sourceId, TwDG.Control, TwDAT.PendingXfers, TwMSG.Reset, pxfr);


标签: c# twain