Tag Archives: Scanner

Using WIA for scanning

I was playing around this morning with scanning images and put together an adapter class that uses the Windows automation library (WIAAUT.DLL) which is part of the WIA automation SDK — WIA means Windows Image Acquisition.

Here are the imports I used for the code file:

 

using System;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Runtime.InteropServices;
using System.Security.Permissions;
using WIA;

 

I created a simple enumeration for some of the more common errors that I expected.

public enum WiaScannerError : uint
{
LibraryNotInstalled = 0x80040154,
OutputFileExists = 0x80070050,
ScannerNotAvailable = 0x80210015,
OperationCancelled = 0x80210064
}

Instead of throwing a COMException I created a special exception class that provides an error code from the aforementioned enumeration.

[Serializable]
public class WiaOperationException : 
Exception
{
private WiaScannerError _errorCode;

     public WiaOperationException(WiaScannerError errorCode)
base()
{
ErrorCode = errorCode;
}

     public WiaOperationException(string message, WiaScannerError errorCode)
base(message)
{
ErrorCode = errorCode;
}

public WiaOperationException(string message, Exception innerException)
base(message, innerException)
{
COMException comException = innerException as COMException;

if (comException != null)
ErrorCode = (WiaScannerError)comException.ErrorCode;
}

     public WiaOperationException(string message, Exception innerException, WiaScannerError errorCode)
base(message, innerException)
{
ErrorCode = errorCode;
}

public WiaOperationException(System.Runtime.Serialization.SerializationInfo info,
System.Runtime.Serialization.StreamingContext context)
base(info, context)
{
info.AddValue(“ErrorCode”, (uint)_errorCode);
}

public WiaScannerError ErrorCode
{
get return _errorCode; }
protected set { _errorCode = value; }
}

public override void GetObjectData(System.Runtime.Serialization.SerializationInfo info,
System.Runtime.Serialization.StreamingContext context)
{
base.GetObjectData(info, context);
ErrorCode = (WiaScannerError)info.GetUInt32(“ErrorCode”);
}
}

The actual class I created is just for scanners, but you can adapt it to any device that supports WIA.  I’ve pulled out comments and removed some extra stuff like providing a friendly message for errors for the sake of brevity.

public sealed class WiaScannerAdapter : IDisposable
{
private CommonDialogClass _wiaManager;
private bool _disposed; 
// indicates if Dispose has been called

    public WiaScannerAdapter()
{
}

~WiaScannerAdapter()
{
Dispose(false);
}

     private CommonDialogClass WiaManager
{
get return _wiaManager; }
set { _wiaManager = value; }
}

[SecurityPermission(SecurityAction.Demand, UnmanagedCode = true)]
     public Image ScanImage(ImageFormat outputFormat, string fileName)
{
if (outputFormat == null)
throw new ArgumentNullException(“outputFormat”);

FileIOPermission filePerm =
new FileIOPermission(FileIOPermissionAccess.AllAccess, fileName));
filePerm.Demand();

ImageFile imageObject = null;

try
{
if (WiaManager == null)
WiaManager = new CommonDialogClass();

imageObject =
WiaManager.ShowAcquireImage(WiaDeviceType.ScannerDeviceType,
WiaImageIntent.ColorIntent, WiaImageBias.MinimizeSize,
outputFormat.Guid.ToString(“B”), falsetruetrue);

imageObject.SaveFile(fileName);
return Image.FromFile(fileName);
}
catch (COMException ex)
{
string message = “Error scanning image“;
throw new WiaOperationException(message, ex);
}
finally
{
if (imageObject != null)
Marshal.ReleaseComObject(imageObject);
}
}

public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}

     private void Dispose(bool disposing)
{
if (!_disposed)
{
if (disposing)
{
// no managed resources to cleanup
}

// cleanup unmanaged resources
if (_wiaManager != null)
Marshal.ReleaseComObject(_wiaManager);

_disposed = true;
}
}
}

Calling the adapter is really easy.  Here’s an example that puts the image into a picturebox:

using (WiaScannerAdapter adapter = new WiaScannerAdapter())
{
try
{
Image image = adapter.ScanImage(ImageFormat.Bmp, @”c:\temp\test.bmp”);
pictureBox1.Image = image;
}
catch (WiaOperationException ex)
{
MessageBox.Show(ex.Message + “ Error Code: “ + ex.ErrorCode);
}
}

      Ref:

http://geekswithblogs.net/tonyt/archive/2006/07/29/86608.aspx

VS 2010 compiler error: Interop type XXX cannot be embedded. Use the applicable interface instead.

In most cases (such as error for the usage of UPnPNATClass as noted in one of the comments) this error is the result of code which tries to instantiate a COM object e.g. here piece of code starting up Excel:

Excel.ApplicationClass xlapp = new Excel.ApplicationClass();

Here it is enough to say that Excel.ApplicationClass derives from Excel.Application interface and one can even instantiate Excel using Excel.Application interface. Rewriting this code as below produces exact same results:

Excel.Application xlapp = new Excel.Application();

Ref: http://blogs.msdn.com/b/mshneer/archive/2009/12/07/interop-type-xxx-cannot-be-embedded-use-the-applicable-interface-instead.aspx

.NET Image Scanner

TWAIN

Windows Image Acquisition (WIA)

Integrate image scanning within a C# application

Now, include the WIA library (C:\Windows\System32\wiaaut.dll) within your project by adding a reference to it :

 

Figure 2.

Add a new class to your project and name it Scanner:

using System;
using WIA;

namespace ScanImage
{
public class Scanner
{
Device oDevice;
Item oItem;
CommonDialogClass dlg;
public Scanner()
{
dlg = new CommonDialogClass();
oDevice = dlg.ShowSelectDevice(WiaDeviceType.ScannerDeviceType, true, false);
}
public void Scann()
{
dlg.ShowAcquisitionWizard(oDevice);
}
}
}

In order to consume the services of this very simple class add a button and a picture box to your form as your project is Windows form one, the form should looks like this bellow:

 

Figure 3.

Do implement the button1_click as follow:

private void button1_Click(object sender, EventArgs e)
{
   Scanner oScanner = new Scanner();
oScanner.Scann();
button1.Text = “Image scanned”;
  OpenFileDialog dlg = new OpenFileDialog();
if (dlg.ShowDialog() == DialogResult.OK)
{
pictureBox1.Image = Image.FromFile(dlg.FileName);
}
}

Now run the application and observe:

 

Figure 4.

Click OK

 

Figure 5.

Then the below windows appears :

Figure 6.

Choose the colored photo, and then click next:

 

Figure 7.

In the above window, select JPG then click next

 

Figure 8 .

As showed above, the scanning process will be lunched as normally, click next then finish and the paper will be scanned as bellow:

 

Figure 9

You can browse to the emplacement of the given scanned image and display it using the picture box.

 

Figure 10

That’s it

 

Ref: http://www.c-sharpcorner.com/uploadfile/yougerthen/integrate-image-scanning-within-a-C-Sharp-application-part-vi/