Scan File From Scanner Using Flatbed And ADF With Windows Image Acquisition (WIA)

In this blog, I am going to give the solution for creating a windows application to connect your system toa scanner and scan the files from the scanner using WIA and save it to your local drive.

WIA (Flatbed and ADF)

Some important points you have to follow before starting the development:
  1. Before starting you should know something about WIA.
  2. Read about Windows image Acquisition properties and features.
  3. You have to import the Interop.WIA.dll
Steps you need to follow for development:
  1. Open your visual studio, go to file and create windows form application.
  2. Select language as c#.
  3. Give your application name as you want.
  4. Now go to the solution explorer right click and add form.
  5. Take one button control.


Now generate the click event of scan button.

Now you have to write the code for calling the scanner properties initializing the device and process , so you have to write this code into your form Initialization event.

Most Important point is You have to add reference of Interop.WIA.dll,
  1. public Form2()  
  2. {  
  3.     InitializeComponent();  
  4.     //Get default device Id  
  5.     _deviceId = FindDefaultDeviceId();  
  6.     //Find Device  
  7.     _deviceInfo = FindDevice(_deviceId);  
  8.     //Connect the device  
  9.     _device = _deviceInfo.Connect();  
  10. }  
  11. private DeviceInfo FindDevice(string deviceId)  
  12. {  
  13.         DeviceManager manager = new DeviceManager();  
  14.         foreach(DeviceInfo info in manager.DeviceInfos)  
  15.         if (info.DeviceID == deviceId)  
  16.             return info;  
  17.         return null;  
  18.     }  
  19.     //finding the device Id here  
  20. private string FindDefaultDeviceId()  
  21. {  
  22.     string deviceId = Properties.Settings.Default.ScannerDeviceID;  
  23.     if (String.IsNullOrEmpty(deviceId))  
  24.     {  
  25.         // Select a scanner  
  26.         WIA.CommonDialog wiaDiag = new WIA.CommonDialog();  
  27.         Device d = wiaDiag.ShowSelectDevice(WiaDeviceType.ScannerDeviceType, truefalse);  
  28.         if (d != null)  
  29.         {  
  30.             deviceId = d.DeviceID;  
  31.             Properties.Settings.Default.ScannerDeviceID = deviceId;  
  32.             Properties.Settings.Default.Save();  
  33.         }  
  34.     }  
  35.     return deviceId;  
  36. }  
Copy and paste below code:
  1. public List < Image > ScanPages(int dpi = 150, double width = 8.5, double height = 11)   
  2. {  
  3.     Item item = _device.Items[1];  
  4.     // configure item of the device  
  5.     SetDeviceItemProperty(ref item, 6146, 2); // greyscale  
  6.     SetDeviceItemProperty(ref item, 6147, dpi); // 150 dpi  
  7.     SetDeviceItemProperty(ref item, 6148, dpi); // 150 dpi  
  8.     SetDeviceItemProperty(ref item, 6151, (int)(dpi * width)); // set scan width  
  9.     SetDeviceItemProperty(ref item, 6152, (int)(dpi * height)); // set scan height  
  10.     SetDeviceItemProperty(ref item, 4104, 8); // bit depth  
  11.     // Detect if the ADF is loaded, if not use the flatbed  
  12.     List < Image > images = GetPagesFromScanner(ScanSource.DocumentFeeder, item);  
  13.     if (images.Count == 0)  
  14.     {  
  15.         // check the flatbed if ADF is not loaded, try from flatbed  
  16.         DialogResult dialogResult;  
  17.         do  
  18.         {  
  19.             List < Image > singlePage = GetPagesFromScanner(ScanSource.Flatbed, item);  
  20.             images.AddRange(singlePage);  
  21.             dialogResult = MessageBox.Show("Do you want to scan another page?""ScanToEvernote", MessageBoxButtons.YesNo);  
  22.         }  
  23.         while (dialogResult == DialogResult.Yes);  
  24.     }  
  25.     return images;  
  26. }  
  27. private List < Image > GetPagesFromScanner(ScanSource source, Item item)  
  28. {  
  29.     SetDeviceProperty(ref _device, 3088, (int) source);  
  30.     List < Image > images = new List < Image > ();  
  31.     int handlingStatus = GetDeviceProperty(ref _device, WIA_DPS_DOCUMENT_HANDLING_STATUS);  
  32.     if ((source == ScanSource.DocumentFeeder && handlingStatus == FEED_READY) || (source == ScanSource.Flatbed && handlingStatus == FLATBED_READY)) {  
  33.         do {  
  34.             ImageFile wiaImage = null;  
  35.             try {  
  36.                 wiaImage = item.Transfer(WIA_FORMAT_JPEG);  
  37.             } catch (COMException ex)   
  38.             {  
  39.                 if ((uint) ex.ErrorCode == WIA_ERROR_PAPER_EMPTY)  
  40.                     break;  
  41.                 else  
  42.                     throw;  
  43.             }  
  44.             if (wiaImage != null)  
  45.             {  
  46.                 System.Diagnostics.Trace.WriteLine(String.Format("Image is {0} x {1} pixels", (float) wiaImage.Width / 150, (float) wiaImage.Height / 150));  
  47.                 Image image = ConvertToImage(wiaImage);  
  48.                 images.Add(image);  
  49.             }  
  50.         }  
  51.         while (source == ScanSource.DocumentFeeder);  
  52.     }  
  53.     return images;  
  54. }  
  55. private static Image ConvertToImage(ImageFile wiaImage)  
  56. {  
  57.     byte[] imageBytes = (byte[]) wiaImage.FileData.get_BinaryData();  
  58.     MemoryStream ms = new MemoryStream(imageBytes);  
  59.     Image image = Image.FromStream(ms);  
  60.     return image;  
  61. }#region Get / set device properties  
  62. private void SetDeviceProperty(ref Device device, int propertyID, int propertyValue)  
  63. {  
  64.     foreach(Property p in device.Properties)  
  65.     {  
  66.         if (p.PropertyID == propertyID)  
  67.         {  
  68.             object value = propertyValue;  
  69.             p.set_Value(ref value);  
  70.             break;  
  71.         }  
  72.     }  
  73. }  
  74. private int GetDeviceProperty(ref Device device, int propertyID)  
  75. {  
  76.     int ret = -1;  
  77.     foreach(Property p in device.Properties)  
  78.     {  
  79.         if (p.PropertyID == propertyID)  
  80.         {  
  81.             ret = (int) p.get_Value();  
  82.             break;  
  83.         }  
  84.     }  
  85.     return ret;  
  86. }  
  87. private void SetDeviceItemProperty(ref Item item, int propertyID, int propertyValue)  
  88. {  
  89.     foreach(Property p in item.Properties)  
  90.     {  
  91.         if (p.PropertyID == propertyID)  
  92.         {  
  93.             object value = propertyValue;  
  94.             p.set_Value(ref value);  
  95.             break;  
  96.         }  
  97.     }  
  98. }  
  99. private int GetDeviceItemProperty(ref Item item, int propertyID)   
  100. {  
  101.     int ret = -1;  
  102.     foreach(Property p in item.Properties)   
  103.     {  
  104.         if (p.PropertyID == propertyID)   
  105.         {  
  106.             ret = (int) p.get_Value();  
  107.             break;  
  108.         }  
  109.     }  
  110.     return ret;  
  111. }#endregion  
  112. private void button1_Click(object sender, EventArgs e)   
  113. {  
  114.     List < Image > obj = ScanPages();  
  115.     //This code i written to upload the file  
  116.     foreach(Image aa in obj)   
  117.     {  
  118.         //aa.Save("D:\\ScanerUploadedFileWIA\\myfile.png _" + DateTime.Now.ToLongTimeString(), ImageFormat.Png);  
  119.         aa.Save(@ "D:\ScanerUploadedFileWIA\" + DateTime.Now.ToString("  
  120.             yyyy - MM - dd HHmmss ") + ".jpeg ", ImageFormat.Jpeg);  
  121.         }  
  122.     }  
  123. }  
  124. enum ScanSource   
  125. {  
  126.     DocumentFeeder = 1,  
  127.         Flatbed = 2,  
  128. }  
Note: Add the final. You have to set the properties of device ID, check the below Image,


This is the final solution with WIA. If you have any doubts and/or problems you can contact me any time.
All the best!