Showing posts with label WIA. Show all posts
Showing posts with label WIA. Show all posts

Wednesday, September 30, 2009

WIA in C# Redux: for Vista!

Of all the insanity! The scanning code I posted earlier does not work with the default configuration of Vista! Vista does not have the wiascr.dll file. However, it does have wiaaut.dll. Code I found at http://www.eggheadcafe.com/community/aspnet/2/76650/heres-some-sample-code.aspx finally gave me the answer after bashing my head around. It was easy to find code that worked for a WebCam, but nearly impossible to find code that worked for the scanner I was using. I guess no one out there uses scanners. Anyway, here's the modified code. Note that I added a ScannerException class--this just inherits the Exception class--nothing special about it:


///
/// This is a simple wrapper around WIA.
///

public class Scanner
{
public class AcquireEventArgs : EventArgs
{
public Image Image { get; internal set; }
}
WIA.DeviceManager manager = new WIA.DeviceManagerClass();

///
/// Acquires the images.
///

public void AcquireImages()
{
WIA.CommonDialogClass diag = new WIA.CommonDialogClass();
System.Object Object1 = null;
System.Object Object2 = null;
WIA.Device dev = null;
try
{
dev = diag.ShowSelectDevice(WIA.WiaDeviceType.UnspecifiedDeviceType, true, false);
}
catch (Exception ex)
{
if (ex.Message.EndsWith("00153.") || ex.Message.EndsWith("21006A."))
{
throw new ScannerException("Scanner Not connected", ex);
}
else
{
throw new ScannerException("Scanner problem", ex);
}

}
if (dev != null)
{


WIA.Item Item1 = ItemObjectReturnedFromInitializingScanner(ref dev);
WIA.ImageFile Image1 = new WIA.ImageFile();
WIA.ImageProcess ImageProcess1 = new WIA.ImageProcess();
Object1 = (Object)"Convert";
ImageProcess1.Filters.Add(ImageProcess1.FilterInfos.get_Item(ref Object1).FilterID, 0);
Object1 = (Object)"FormatID";
Object2 = (Object)WIA.FormatID.wiaFormatTIFF;
ImageProcess1.Filters[1].Properties.get_Item(ref Object1).set_Value(ref Object2);
Object1 = (Object)"Compression";
Object2 = (Object)"CCITT4";
ImageProcess1.Filters[1].Properties.get_Item(ref Object1).set_Value(ref Object2);
Object1 = null;
Object2 = null;


try
{
WIA.ImageFile imagefile = Item1.Transfer(WIA.FormatID.wiaFormatTIFF) as WIA.ImageFile;

if (ImageScanned != null)
{
AcquireEventArgs e = new AcquireEventArgs();
using (MemoryStream ms = new MemoryStream((byte[])imagefile.FileData.get_BinaryData()))
{
e.Image = new Bitmap(ms);
}
ImageScanned(this, e);
}
}
catch (Exception ex)
{
throw new ScannerException("Problem with Scanner", ex);
}
}
}

private WIA.Item ItemObjectReturnedFromInitializingScanner(ref WIA.Device Scanner)
{
WIA.Item Item1 = null;
Object Object1 = null;
Object Object2 = null;
Int32 DPI = 200;
foreach (WIA.Item CurrentItem in Scanner.Items) // 'Scanner settings.
{

Item1 = CurrentItem;
try
{
Object1 = (Object)"6146";
Object2 = (Object)4;
CurrentItem.Properties.get_Item(ref Object1).set_Value(ref Object2);
}
catch
{ }
try
{
Object1 = (Object)"6147";
Object2 = (Object)DPI;
CurrentItem.Properties.get_Item(ref Object1).set_Value(ref Object2);
}
catch
{ }
try
{
Object1 = (Object)"6148";
Object2 = (Object)DPI;
CurrentItem.Properties.get_Item(ref Object1).set_Value(ref Object2);
}
catch
{ }
try
{
Object1 = (Object)"6149";
Object2 = (Object)0;
CurrentItem.Properties.get_Item(ref Object1).set_Value(ref Object2);
}
catch
{ }
try
{
Object1 = (Object)"6150";
Object2 = (Object)0;
CurrentItem.Properties.get_Item(ref Object1).set_Value(ref Object2);
}
catch
{ }
try
{
Object1 = (Object)"6151";
Object2 = (Object)(8.5 * DPI);
CurrentItem.Properties.get_Item(ref Object1).set_Value(ref Object2);
}
catch
{ }
try
{
Object1 = (Object)"6152";
Object2 = (Object)(11.5 * DPI);
CurrentItem.Properties.get_Item(ref Object1).set_Value(ref Object2);
}
catch
{ }

foreach (WIA.Property Prop in Scanner.Properties)
{
if (Prop.PropertyID == 3088) //
{
try
{
Object1 = (Object)5;
Prop.set_Value(ref Object1); //'This is my effort to enforce duplex. I
}
catch (Exception) { }
}
}
}
Object1 = null;
Object2 = null;
return Item1;
}

///
/// Occurs when [image scanned].
///

public event EventHandler ImageScanned;


}

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);
            }
        }
    }
}