I have made a user control to scan the documents from attached scanner.
Here I can explain the details.

In the attached form image there are 2 picture boxes, a preview button, a save button, two labels for showing save path and a drop down to show available scanner devices. See the image above to get a clear picture about the form design.
There is a class file named WIAScanner.cs, see the the code below
using System;
using System.Collections.Generic;
using System.IO;
using System.Drawing;
using WIA;
namespace TESTSCAN
{
class WIAScanner
{
const string wiaFormatBMP = "{B96B3CAB-0728-11D3-9D7B-0000F81EF32E}";
const string WIA_DEVICE_PROPERTY_PAGES_ID = "3096";
const string WIA_SCAN_BRIGHTNESS_PERCENTS = "6154";
const string WIA_SCAN_CONTRAST_PERCENTS = "6155";
const string WIA_SCAN_COLOR_MODE = "6146";
class WIA_DPS_DOCUMENT_HANDLING_SELECT
{
public const uint FEEDER = 0x00000001;
public const uint FLATBED = 0x00000002;
}
class WIA_DPS_DOCUMENT_HANDLING_STATUS
{
public const uint FEED_READY = 0x00000001;
}
class WIA_PROPERTIES
{
public const uint WIA_RESERVED_FOR_NEW_PROPS = 1024;
public const uint WIA_DIP_FIRST = 2;
public const uint WIA_DPA_FIRST = WIA_DIP_FIRST + WIA_RESERVED_FOR_NEW_PROPS;
public const uint WIA_DPC_FIRST = WIA_DPA_FIRST + WIA_RESERVED_FOR_NEW_PROPS;
public const uint WIA_DPS_FIRST = WIA_DPC_FIRST + WIA_RESERVED_FOR_NEW_PROPS;
public const uint WIA_DPS_DOCUMENT_HANDLING_STATUS = WIA_DPS_FIRST + 13;
public const uint WIA_DPS_DOCUMENT_HANDLING_SELECT = WIA_DPS_FIRST + 14;
}
public static List<Image> Scan()
{
WIA.ICommonDialog dialog = new WIA.CommonDialog();
WIA.Device device = dialog.ShowSelectDevice(WIA.WiaDeviceType.UnspecifiedDeviceType, true, false);
if (device != null)
{
return Scan(device.DeviceID,1);
}
else
{
throw new Exception("You must select a device for scanning.");
}
}
public static List<Image> Scan(string scannerId, int pages)
{
List<Image> images = new List<Image>();
bool hasMorePages = true;
int numbrPages = pages;
while (hasMorePages)
{
WIA.DeviceManager manager = new WIA.DeviceManager();
WIA.Device device = null;
foreach (WIA.DeviceInfo info in manager.DeviceInfos)
{
if (info.DeviceID == scannerId)
{
device = info.Connect();
break;
}
}
if (device == null)
{
string availableDevices = "";
foreach (WIA.DeviceInfo info in manager.DeviceInfos)
{
availableDevices += info.DeviceID + "\n";
}
throw new Exception("The device with provided ID could not be found. Available Devices:\n" + availableDevices);
}
SetWIAProperty(device.Properties, WIA_DEVICE_PROPERTY_PAGES_ID, 1);
WIA.Item item = device.Items[1] as WIA.Item;
AdjustScannerSettings(item, 150, 0, 0, 1250, 1700, 0, 0, 1);
try
{
WIA.ICommonDialog wiaCommonDialog = new WIA.CommonDialog();
WIA.ImageFile image = (WIA.ImageFile)wiaCommonDialog.ShowTransfer(item, wiaFormatBMP, false);
string fileName = Path.GetTempFileName();
File.Delete(fileName);
image.SaveFile(fileName);
image = null;
images.Add(Image.FromFile(fileName));
}
catch (Exception exc)
{
throw exc;
}
finally
{
item = null;
WIA.Property documentHandlingSelect = null;
WIA.Property documentHandlingStatus = null;
foreach (WIA.Property prop in device.Properties)
{
if (prop.PropertyID == WIA_PROPERTIES.WIA_DPS_DOCUMENT_HANDLING_SELECT)
documentHandlingSelect = prop;
if (prop.PropertyID == WIA_PROPERTIES.WIA_DPS_DOCUMENT_HANDLING_STATUS)
documentHandlingStatus = prop;
}
hasMorePages = false;
if (documentHandlingSelect != null)
{
if ((Convert.ToUInt32(documentHandlingSelect.get_Value()) & WIA_DPS_DOCUMENT_HANDLING_SELECT.FEEDER) != 0)
{
hasMorePages = ((Convert.ToUInt32(documentHandlingStatus.get_Value()) & WIA_DPS_DOCUMENT_HANDLING_STATUS.FEED_READY) != 0);
}
}
}
numbrPages -= 1;
if (numbrPages > 0)
hasMorePages = true;
else
hasMorePages = false;
}
return images;
}
public static List<string> GetDevices()
{
List<string> devices = new List<string>();
WIA.DeviceManager manager = new WIA.DeviceManager();
foreach (WIA.DeviceInfo info in manager.DeviceInfos)
{
devices.Add(info.DeviceID);
}
return devices;
}
private static void SetWIAProperty(WIA.IProperties properties,
object propName, object propValue)
{
WIA.Property prop = properties.get_Item(ref propName);
prop.set_Value(ref propValue);
}
private static void AdjustScannerSettings(IItem scannnerItem, int scanResolutionDPI, int scanStartLeftPixel, int scanStartTopPixel,
int scanWidthPixels, int scanHeightPixels, int brightnessPercents, int contrastPercents, int colorMode)
{
const string WIA_SCAN_COLOR_MODE = "6146";
const string WIA_HORIZONTAL_SCAN_RESOLUTION_DPI = "6147";
const string WIA_VERTICAL_SCAN_RESOLUTION_DPI = "6148";
const string WIA_HORIZONTAL_SCAN_START_PIXEL = "6149";
const string WIA_VERTICAL_SCAN_START_PIXEL = "6150";
const string WIA_HORIZONTAL_SCAN_SIZE_PIXELS = "6151";
const string WIA_VERTICAL_SCAN_SIZE_PIXELS = "6152";
const string WIA_SCAN_BRIGHTNESS_PERCENTS = "6154";
const string WIA_SCAN_CONTRAST_PERCENTS = "6155";
SetWIAProperty(scannnerItem.Properties, WIA_HORIZONTAL_SCAN_RESOLUTION_DPI, scanResolutionDPI);
SetWIAProperty(scannnerItem.Properties, WIA_VERTICAL_SCAN_RESOLUTION_DPI, scanResolutionDPI);
SetWIAProperty(scannnerItem.Properties, WIA_HORIZONTAL_SCAN_START_PIXEL, scanStartLeftPixel);
SetWIAProperty(scannnerItem.Properties, WIA_VERTICAL_SCAN_START_PIXEL, scanStartTopPixel);
SetWIAProperty(scannnerItem.Properties, WIA_HORIZONTAL_SCAN_SIZE_PIXELS, scanWidthPixels);
SetWIAProperty(scannnerItem.Properties, WIA_VERTICAL_SCAN_SIZE_PIXELS, scanHeightPixels);
SetWIAProperty(scannnerItem.Properties, WIA_SCAN_BRIGHTNESS_PERCENTS, brightnessPercents);
SetWIAProperty(scannnerItem.Properties, WIA_SCAN_CONTRAST_PERCENTS, contrastPercents);
SetWIAProperty(scannnerItem.Properties, WIA_SCAN_COLOR_MODE, colorMode);
}
}
}
Then see below the .cs file of the form named Form1
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Drawing.Imaging;
using System.Drawing.Drawing2D;
namespace TESTSCAN
{
public partial class Form1 : Form
{
int cropX, cropY, cropWidth, cropHeight;
Pen borderpen = new Pen(Color.Red, 2);
Image _orgImage;
Bitmap crop;
List<string> devices;
SolidBrush rectbrush = new SolidBrush(Color.FromArgb(100, Color.White));
int pages;
int currentPage = 0;
public Form1()
{
InitializeComponent();
IsSaved = false;
}
List<Image> images;
private string f_path;
private string doc_no;
private bool savedOrNot = false;
private List<string> fNames;
public List<string> fileNames
{
get { return fNames; }
set { fNames = value; }
}
public String SavePath
{
get { return f_path; }
set { f_path = value; }
}
public String DocNo
{
get { return doc_no; }
set { doc_no = value; }
}
public bool IsSaved
{
get { return savedOrNot; }
set { savedOrNot = value; }
}
private void Form1_Load(object sender, EventArgs e)
{
lblPath.Text = SavePath;
lblDocNo.Text = DocNo;
devices = WIAScanner.GetDevices();
foreach (string device in devices)
{
lbDevices.Items.Add(device);
}
if (lbDevices.Items.Count != 0)
{
lbDevices.SelectedIndex = 0;
}
}
private void btnPreview_Click(object sender, EventArgs e)
{
try
{
if (lbDevices.Items.Count == 0)
{
MessageBox.Show("You do not have any WIA devices.");
}
else
{
pages =3;
images = WIAScanner.Scan((string)lbDevices.SelectedItem, pages);
pages = images.Count;
if (images != null)
{
foreach (Image image in images)
{
pic_scan.Image = images[0];
pic_scan.Show();
pic_scan.SizeMode = PictureBoxSizeMode.StretchImage;
_orgImage = images[0];
crop = new Bitmap(images[0]);
btnOriginal.Enabled = true;
btnSave.Enabled = true;
currentPage = 0;
}
}
}
}
catch (Exception exc)
{
MessageBox.Show(exc.Message);
}
}
List<string> sss = new List<string>();
private void btnSave_Click(object sender, EventArgs e)
{
try
{
if (crop != null)
{
SavePath = @"D:\NAJEEB\scanned images\";
DocNo = "4444";
string currentFName = DocNo + Convert.ToString(currentPage + 1) + ".jpeg";
crop.Save(SavePath + currentFName, ImageFormat.Jpeg);
sss.Add(currentFName);
MessageBox.Show("Document Saved Successfully");
IsSaved = true;
currentPage += 1;
if (currentPage < (pages))
{
pic_scan.Image = images[currentPage];
pic_scan.Show();
pic_scan.SizeMode = PictureBoxSizeMode.StretchImage;
_orgImage = images[currentPage];
crop = new Bitmap(images[currentPage]);
btnOriginal.Enabled = true;
btnSave.Enabled = true;
}
else
{ btnSave.Enabled =false;
fileNames = sss;
}
}
}
catch (Exception exc)
{
IsSaved = false;
MessageBox.Show(exc.Message);
}
}
private void btnOriginal_Click(object sender, EventArgs e)
{
if (_orgImage != null)
{
crop = new Bitmap(_orgImage);
pic_scan.Image = _orgImage;
pic_scan.SizeMode = PictureBoxSizeMode.StretchImage;
pic_scan.Refresh();
}
}
private void pic_scan_MouseDown(object sender, MouseEventArgs e)
{
try
{
if (e.Button == MouseButtons.Left)
{
pic_scan.Refresh();
cropX = e.X;
cropY = e.Y;
Cursor = Cursors.Cross;
}
pic_scan.Refresh();
}
catch { }
}
private void pic_scan_MouseMove(object sender, MouseEventArgs e)
{
try
{
if (pic_scan.Image == null)
return;
if (e.Button == MouseButtons.Left)
{
pic_scan.Refresh();
cropWidth = e.X - cropX;
cropHeight = e.Y - cropY;
}
pic_scan.Refresh();
}
catch { }
}
private void pic_scan_MouseUp(object sender, MouseEventArgs e)
{
try
{
Cursor = Cursors.Default;
if (cropWidth < 1)
{
return;
}
Rectangle rect = new Rectangle(cropX, cropY, cropWidth, cropHeight);
Bitmap bit = new Bitmap(pic_scan.Image, pic_scan.Width, pic_scan.Height);
crop = new Bitmap(cropWidth, cropHeight);
Graphics gfx = Graphics.FromImage(crop);
gfx.InterpolationMode = InterpolationMode.HighQualityBicubic;
gfx.PixelOffsetMode = PixelOffsetMode.HighQuality;
gfx.CompositingQuality = CompositingQuality.HighQuality;
gfx.DrawImage(bit, 0, 0, rect, GraphicsUnit.Pixel);
}
catch { }
}
private void pic_scan_Paint(object sender, PaintEventArgs e)
{
Rectangle rect = new Rectangle(cropX, cropY, cropWidth, cropHeight);
Graphics gfx = e.Graphics;
gfx.DrawRectangle(borderpen, rect);
gfx.FillRectangle(rectbrush, rect);
}
}
}
Short description of the working flow:
- On form load event the available scanner devices adding to drop down list.
The user can select any device from this drop down.
- On Preview button click, the document is scanned to application and is shown in the picture box.
- There is another picture box in the form for keeping the cropped image. If you select any area from the picture in the picture box then you will feel the cropping effect. The cropped image keep in the second picture box placed behind the first picture box.
- On save button click the image save into the specified location in the disk.
This location we can configure from the application. See the code.