Thursday, September 17, 2009

WIA in C#

Been awhile.  Ran into a problem of needing to write code to acquire an image from a scanner.  I had done TWAIN coding, but I've found that TWAIN is now gone by the wayside--in otherwords, don't use it.
 
Instead, use WIA.  I had found Microsoft's WIA SDK, but discovered that its examples are in VB6, to give you an idea how old the stuff is.  And on top of it--it seemed a bit convoluted.
 
Then I ran into http://www.codeproject.com/KB/dotnet/wiascriptingdotnet.aspx, which had a good example, though a little on the incomplete side (he left off the variable declaration statements).  It seemed too simple, but I tried it out. 
 
And wouldn't you know it--that was all that was needed!  The link also include video information, but that was beyond the scope of my project.
 
Below is my code which wraps the WIA (strongly based on the above link).  All you need to do is create the Scanner object, assign the "ImageScanned" event, the call the AcquireImages method.  This code works asynchronously, so you can have other things going on while you wait for the images:
 

using System;
using System.Collections.Generic;
using System.Drawing;
using System.IO;
using System.Runtime.InteropServices;
using WIALib;
namespace WIAWrapper
{
    /// <summary>
   
/// This is a simple wrapper around WIA.
   
/// </summary>
    public class Scanner
    {
        public class AcquireEventArgs : EventArgs
       
{
           
public Image Image { get; internal set; }
        }
        object selectUsingUI = System.Reflection.Missing.Value;
        ItemClass wiaRoot;
        WIALib.
WiaClass wiaManager;
        public Scanner()
        {
            wiaManager =
new WIALib.WiaClass();
            wiaRoot = (
ItemClass)wiaManager.Create(ref selectUsingUI);
        }
        /// <summary>
       
/// Acquires the images.
       
/// </summary>
        public void AcquireImages()
        {
            List<Image> retVal = new List<Image>();
            CollectionClass wiaPics = wiaRoot.GetItemsFromUI(WiaFlag.SingleImage, WiaIntent.ImageTypeColor) as CollectionClass;
            wiaManager.OnTransferComplete +=
new _IWiaEvents_OnTransferCompleteEventHandler(wiaManager_OnTransferComplete);
            foreach (object wiaObj in wiaPics)
            {
                ItemClass wiaItem = (ItemClass)Marshal.CreateWrapperOfType(wiaObj, typeof(ItemClass));
                string imgFile = Path.GetTempFileName();
                wiaItem.Transfer(imgFile,
true);
            }
        }

        public event EventHandler<AcquireEventArgs> ImageScanned;

        /// <summary>
       
/// Wias the manager_ on transfer complete.
       
/// </summary>
       
/// <param name="Item">The item.</param>
       
/// <param name="Path">The path.</param>
        void wiaManager_OnTransferComplete(Item Item, string Path)
       
{
            if (ImageScanned != null)
            {
                AcquireEventArgs e = new AcquireEventArgs();
                e.Image =
new Bitmap(Path);
                ImageScanned(
this, e);
            }
        }
    }
}

No comments:

Post a Comment