Using an ADF Scanner from C#

We have an example project for C# that shows how to use the csXImage ActiveX control to acquire multiple images from a Twain enabled scanner that has an auto document feeder (ADF). The project files can be downloaded.

The demo uses the trial version of csXImage, which must must be registered on the development computer and the licence file must be in the same folder as the .ocx control. Running our installer will have performed the registration and unpacking of files.

When the form is loaded an event runs to populate the combo boxes to request the number of pages to scan. This makes it easier to follow than setting the values in the IDE.

Here is a screenshot of the application after the form has loaded. There are some simple options available that demonstrate some important techniques. Options inlcude whether to use the built in user interface supplied with the scanner and whether to use duplex scanning. The resulting scan is saved and options include separate TIFF files, a single multipage TIFF file, or separate multipage TIFF files where a blank separator page is used between documents.

Demo project using C# with an ADF Twain scanner

The working part of the code is in two sections. The button marked "Acquire" starts the scanning process. After each page is scanned an event is triggered by csXImage, the OnAcquire event, and this event handler contains the code that processes each image.

The SelectTwainDevice method calls a standard dialogue box from Twain to select an installed device from a list. The HasADF property is queried to see if the device actually has an ADF fitted and if not, the user is given the option to cancel or continue. The properties TwainMultiImage and UseADF are both set to true before scanning starts. The TwainImagesToRead property is set, either to zero if all the pages in the feeder are to be read, or to a fixed number of pages. The BlankTol property is used to define a blank page.

Other properties to set first, based on values returned from the form, are UseTwainInterface and TwainDuplexEnabled. The ClearTIF method is called so that any multipage TIFF already in memory is removed before creating another. The Acquire method starts the scan.

private void cmdAcquire_Click(object sender, EventArgs e)
{
  Boolean cancel = false;

  if (axImageBox1.SelectTwainDevice())
  {
    if (!axImageBox1.HasADF)
      if (MessageBox.Show("No ADF detected for this device. Continue?", "",
          MessageBoxButtons.OKCancel) == System.Windows.Forms.DialogResult.Cancel)
        cancel = true;
  }
  else
    cancel = true;

  if (!cancel)
  {
    axImageBox1.TwainMultiImage = true;
    axImageBox1.UseADF = true;
    if (cboPages.Text == "Max.")
      // Continues acquiring images until ADF is empty
      axImageBox1.TwainImagesToRead = 0;
    else
      axImageBox1.TwainImagesToRead = int.Parse(cboPages.Text);
    // This value is the tolerance for defining a blank page. It is set to a high
    // value to ensure this demo will
    // work well even with colour scanning using sheets that are not pure white.
    // For black and white scanning with plain white separator pages a lower value
    // (eg 100) is appropriate.
    axImageBox1.BlankTol = 10000;
    axImageBox1.ClearTIF();
    axImageBox1.UseTwainInterface = chkUI.Checked;
    axImageBox1.TwainDuplexEnabled = chkDuplex.Checked;

    axImageBox1.Acquire();

    if (rdbMulti.Checked)
      axImageBox1.WriteTIF(txtFileName.Text + ".tif");
    if (rdbSep.Checked)
      axImageBox1.WriteTIF(txtFileName.Text + fileNum.ToString().Trim() + ".tif");
  }
}

The OnAcquire event is triggered after each page is scanned and the event handler can be used to run code to process each image. The control is redrawn so that the current image is displayed. Then the image is either saved as an individual TIFF file or it is written into a multipage TIFF which is stored in memory until it is saved later. There is some conditional logic to deal with the different options selected by the user.

An important point is that when a multipage document is created, the Compression and ColorFormat properties are set before calling AddToTIF. These properties apply to each page, not to the entire document.

private void axImageBox1_OnAcquire(object sender, EventArgs e)
{
  // Redraw the control to display the current image
  axImageBox1.Redraw();

  if (rdbSingle.Checked)
  {
    // Save image as an individual file
    axImageBox1.SaveToFile(txtFileName.Text + fileNum.ToString().Trim() + ".tif");
    fileNum++;
  }
  else
    if (rdbMulti.Checked)
    {
      // Save multi-page TIFF file
      // Use Group 4 compression for black and white images
      if (axImageBox1.ColorFormat == csXImageTrial.TxColorFormat.cfMonoBW)
        axImageBox1.Compression = csXImageTrial.TxCompression.cmGroup4;
      axImageBox1.AddToTIF(0);
    }
    else
    {
      if (axImageBox1.IsBlank)
      {
        axImageBox1.WriteTIF(txtFileName.Text + fileNum.ToString().Trim() + ".tif");
        fileNum++;
        axImageBox1.ClearTIF();
      }
      else
        axImageBox1.AddToTIF(0);
  }
}