Batch Scanning

 

If the scanner has an ADF (automatic document feeder) you can use Software Batch scanning. In this case you can scan papers to single pages or to multipage TIFF files. You can choose the compression of the file before scanning using the SetBatchScanImageCompression function/method. In this case, the scanner generates a DIB in memory and the BiTwain saves the DIB to the disk as a TIFF file.

 

If the scanner is a high speed scanner with an ADF use the Hardware Batch scanning. In this case the scanner generates files according to the ICAP_IMAGEFILEFORMAT. If the image file format is a single page format, the files will be indexed (for example test00001.bmp, test00002.bmp etc). If the file format is multipage, such as TIFF, the scanner acquires pages to a multipage TIFF file.

 

The difference between BatchScan function and Acquire function is that BatchScan always transfers the images to the BiTwain.dll in memory (TWSX_NATIVE mode) and uses the BiTIFF.dll to save the images to a TIFF file.

 

If a filename is given, Acquire function saves the images to disk directly in a format the scanner driver supports (TWSX_FILE mode), or returns a handle to a DIB if NULL is passed in the filename parameter (TWSX_NATIVE mode). When using Acquire with TWSX_FILE mode, the supported file type also depends on the scanner driver capability. Some scanner supports only bmp (bitmap) and some scanner supports multiple file types.

 

In the Twain C++ Sample, the “Software Batch Scan” option uses the BatchScan function; “Hardware Batch Scan” uses Acquire with TWSX_FILE mode.

 

Scanners are required to support TWSX_NATIVE transfer mode, but not required to support TWSX_FILE transfer mode, so BatchScan should work in all cases.

 

Before batch scanning you should specify some capabilities:

 

  1. Enable the feeder so that the scanner will scan from the feeder. (SetFeederEnable)

  2. Set ICAP_AUTOFEED. The TWAIN source will automatically feed the next page from the document feeder.

  3. Set the number of pages to scan.

 

Using the BiDisp controls to display scanned pages:

 

The BiDisp control can only display a single page at a time. A DIB image can only contain a single page. When batch scanning is used, the BatchPageDone event will be called for each page, passing a DIB for each page. One should store the DIB for each page. To display multi-page images, one can either create a single BiDisp control or add a buttons to your web page that change the page in the BiDisp control, or you can use multiple BiDisp controls.

 

To combine the DIBs into a single, multi-page TIFF file, you can use the InsertTiffImage method of the BiTIFF control. For more information about the InsertTiffImage method, please see the following page in the manual: http://www.blackice.com/Help/Tools/Document%20Imaging%20OCX%20webhelp/WebHelp/InsertTiffImage_Method.htm

 

[C++]

 

/* Batch Scanning */

 

#include “BiTwain.h”

 

// Set CAP_FEEDERENABLED

CListBox* pMsgBox = (CListBox*)GetDlgItem(IDC_LIST);

TCHAR szTemp[32];

TCHAR szError[128], szMsg[128];

DWORD dwNeeded;

 

int err = GetFeederEnabled(&iEnabled);

if (err != TW_OK)

{

            GetErrorString(err, szError, 128, &dwNeeded);

            _stprintf(szMsg, _T("Getting current value of

CAP_FEEDERENABLED failed. Error: %s"), szError);

            pMsgBox->AddString(szMsg);

            return;

}

 

if (!iEnabled)

{

            err = SetFeederEnable(TRUE);

 

            if (err != TW_OK)

            {

                        GetErrorString(err, szError, 128, &dwNeeded);

                        _stprintf(szMsg, _T("Setting current value of

CAP_FEEDERENABLED failed. Error: %s"), szError);

                        pMsgBox->AddString(szMsg);

                        return;

            }

}

 

// Set CAP_AUTOFEED

DWORD dwReturned;

LPSTR szValue = NULL;

 

err = GetCapabilityOneValue(CAP_AUTOFEED, MSG_GETCURRENT,

NULL, 0, &dwNeeded, &dwReturned);

 

if (dwNeeded > 0)

{

            szValue = (LPSTR)calloc(dwNeeded, sizeof(char));

            if (szValue)

            {

                        err = GetCapabilityOneValue(CAP_AUTOFEED,

MSG_GETCURRENT, szValue, dwNeeded, &dwNeeded,

&dwReturned);

 

                        if (err == TW_OK)

                                    iEnabled = atoi(szValue);

                        else

                        {

                                    GetErrorString(err, szError, 128,

&dwNeeded);

                                    _stprintf_s(szMsg, _T("Getting current value of

CAP_AUTOFEED failed. Error: %s"), szError);

                                    pMsgBox->AddString(szMsg);

                        }

 

                        free(szValue);

            }

            else

            {

                        pMsgBox->AddString(_T("Memory allocation error"));

            }

 

}

else

{

            GetErrorString(err, szError, 128, &dwNeeded);

            _stprintf(szMsg, _T("Getting current value of CAP_AUTOFEED

failed. Error: %s"), szError);

            pMsgBox->AddString(szMsg);

}         

 

if (!iEnabled)

{

            err = SetCapabilityOneNumValue(CAP_AUTOFEED, MSG_SET,

TRUE);

 

            if (err != TW_OK)

            {

                        pMsgBox->AddString(_T("Unable to set CAP_AUTOFEED

capability"));

                        return;

            }

}

 

err = IsFeederLoaded(&iEnabled);

 

if (err == TW_OK)

{

            if (!iEnabled)

            {

                        pMsgBox->AddString(_T("Feeder is empty."));

                        pMsgBox->SetTopIndex(pMsgBox->GetCount()-2);

                        return;

            }

}

else

{

            GetErrorString(err, szError, 128, &dwNeeded);

            _stprintf(szMsg, _T("Getting current value of

CAP_FEEDERLOADED failed. Error: %s"), szError);

            pMsgBox->AddString(szMsg);

            return;

}

 

/* Software batch scanning */

SetBatchScanImageCompression((int)TCOMP_NOCOMP);

BatchScan(_T(“C:\\Images\\Test.tif”), TRUE, 3);

 

[C#]

 

/* Batch Scanning */

 

int err;

string szData;

bool bEnable;

 

// Try to set Bacth Scan Capabilities

bEnable = BiTwain.GetFeederEnabled();

                                   

if (BiTwain.ErrorCode !=

(int)BITWAINLib.enumErrorCodes.TW_OK)

{

            LBLIST.Items.Add("Getting current value of

CAP_FEEDERENABLED failed. Error: " +

BiTwain.GetErrorString(BiTwain.ErrorCode));

            return;

}

 

if (!bEnable)

{

            err = BiTwain.SetFeederEnable(true);

 

            if (err != (int)BITWAINLib.enumErrorCodes.TW_OK)

            {

                        LBLIST.Items.Add("Setting current value of

CAP_FEEDERENABLED failed. Error: " +

BiTwain.GetErrorString(BiTwain.ErrorCode));

                        return;

            }

}

 

// Set CAP_AUTOFEED

szData = BiTwain.GetCapabilityOneValue

((int)BITWAINLib.enumCapabilities.CAP_AUTOFEED, (int)BITWAINLib.enumCapabilityOperations.MSG_GETCURRENT);

                                   

if (BiTwain.ErrorCode !=

(int)BITWAINLib.enumErrorCodes.TW_OK)

{

            LBLIST.Items.Add("Getting current value of

CAP_AUTOFEED failed. Error: " +

BiTwain.GetErrorString(BiTwain.ErrorCode));

            return;

}

 

if (Convert.ToInt32(szData) == 0)

{

            err = BiTwain.SetCapabilityOneNumValue

((int)BITWAINLib.enumCapabilities.CAP_AUTOFEED, (int)BITWAINLib.enumCapabilityOperations.MSG_SET, (float)1.0);

 

if (err != (int)BITWAINLib.enumErrorCodes.TW_OK)

{

                        LBLIST.Items.Add("Setting current value of

CAP_AUTOFEED failed. Error: " +

BiTwain.GetErrorString(BiTwain.ErrorCode));

                        return;

}

 

}

 

// Verify feeder loaded

if (BiTwain.IsFeederLoaded() == false)

{

            LBLIST.Items.Add("Feeder is empty" +

BiTwain.GetErrorString(BiTwain.ErrorCode));

            return;

}

 

/* Software batch scanning */

 

BiTwain.SetBatchScanImageCompression(201); // TCOMP_NOCOMP

BiTwain.BatchScanImageCount = 3;

BiTwain.FileAcquire = “C:\\Images\\Test.tif”;

BiTwain.MultiPage = true;

BiTwain.Action = (short)BITWAINLib.enumScanOperations.TWSTAT_BATCHSCAN;