Get images from scanner, webcam or any other type of imaging device
Here’s the class that I wrote to extract images from various imaging devices via VB.NET and C#.
WIA (Windows Image Acquisition) supports the following types of devices:
- Scanners
- Digital Cameras
- Webcams
The class correctly communicates with Windows Image Acquisition Library (WIALib), releases all COM objects used and allows you to select between single image or multiple images acquisition.
Downloadable package contains actual library that can be used with any of your projects and two demo projects (VB.NET and C#).
If you don’t want to download source code, you can copy it from the code box below.
WIA Wrapper Library, VB.NET Version
Imports System.Drawing Imports System.Runtime.InteropServices Imports WIALib Imports System.IO Public Class ImageRetriever Public Function RetriveImages(ByVal selectionMode As ImageSelectionMode) As List(Of Bitmap) Dim comObjects As New List(Of Object) 'Create WIA COM objects 'Manager Dim manager As WiaClass = Nothing comObjects.Add(manager) 'Devices collection Dim devices As CollectionClass = Nothing comObjects.Add(devices) 'Root device Dim rootDevice As ItemClass = Nothing comObjects.Add(rootDevice) 'Collection Dim pictures As CollectionClass = Nothing comObjects.Add(pictures) 'Image Dim pictureItem As ItemClass = Nothing comObjects.Add(pictureItem) manager = New WiaClass() devices = TryCast(manager.Devices, CollectionClass) 'Retrieve all devices If (devices Is Nothing) OrElse (devices.Count = 0) Then DisposeComObjects(comObjects) Throw New AcquisitionException("No devices found.") End If Dim UISelection As Object = System.Reflection.Missing.Value 'WIA dialog, allows user to select a device rootDevice = DirectCast(manager.Create(UISelection), ItemClass) If rootDevice Is Nothing Then Throw New AcquisitionException("No device selected.") End If 'WIA dialog, allows user to select a picture. Dim flag As WiaFlag = WiaFlag.SingleImage If selectionMode = ImageSelectionMode.Multiple Then flag = WiaFlag.UseCommonUI pictures = TryCast(rootDevice.GetItemsFromUI(flag, WiaIntent.ImageTypeColor), CollectionClass) If pictures Is Nothing Then DisposeComObjects(comObjects) Throw New AcquisitionException("No pictures selected.") End If Dim bitmapList As New List(Of Bitmap) For Each picture As Object In pictures Dim filePath As String = Path.GetTempFileName pictureItem = DirectCast(Marshal.CreateWrapperOfType(picture, GetType(ItemClass)), ItemClass) pictureItem.Transfer(filePath, False) bitmapList.Add(Image.FromFile(filePath)) 'Release COM object Marshal.ReleaseComObject(picture) Next Return bitmapList DisposeComObjects(comObjects) End Function Private Sub DisposeComObjects(ByVal objects As List(Of Object)) For Each comObject In objects If comObject IsNot Nothing Then Marshal.ReleaseComObject(comObject) End If Next End Sub End Class Public Class AcquisitionException Inherits Exception Public Sub New(ByVal message As String) MyBase.New(message) End Sub End Class Public Enum ImageSelectionMode One = 0 Multiple = 1 End Enum |
WIA Wrapper Class, CSharp version
using System.Drawing; using System.Runtime.InteropServices; using WIALib; using System.IO; public class ImageRetriever { public List<Bitmap> RetriveImages(ImageSelectionMode selectionMode) { List<object> comObjects = new List<object>(); //Create WIA COM objects //Manager WiaClass manager = null; comObjects.Add(manager); //Devices collection CollectionClass devices = null; comObjects.Add(devices); //Root device ItemClass rootDevice = null; comObjects.Add(rootDevice); //Collection CollectionClass pictures = null; comObjects.Add(pictures); //Image ItemClass pictureItem = null; comObjects.Add(pictureItem); manager = new WiaClass(); devices = manager.Devices as CollectionClass; //Retrieve all devices if ((devices == null) || (devices.Count == 0)) { DisposeComObjects(comObjects); throw new AcquisitionException("No devices found."); } object UISelection = System.Reflection.Missing.Value; //WIA dialog, allows user to select a device rootDevice = (ItemClass)manager.Create(UISelection); if (rootDevice == null) { throw new AcquisitionException("No device selected."); } //WIA dialog, allows user to select a picture. WiaFlag flag = WiaFlag.SingleImage; if (selectionMode == ImageSelectionMode.Multiple) flag = WiaFlag.UseCommonUI; pictures = rootDevice.GetItemsFromUI(flag, WiaIntent.ImageTypeColor) as CollectionClass; if (pictures == null) { DisposeComObjects(comObjects); throw new AcquisitionException("No pictures selected."); } List<Bitmap> bitmapList = new List<Bitmap>(); foreach (object picture in pictures) { string filePath = Path.GetTempFileName; pictureItem = (ItemClass)Marshal.CreateWrapperOfType(picture, typeof(ItemClass)); pictureItem.Transfer(filePath, false); bitmapList.Add(Image.FromFile(filePath)); //Release COM object Marshal.ReleaseComObject(picture); } return bitmapList; DisposeComObjects(comObjects); } private void DisposeComObjects(List<object> objects) { foreach (var comObject in objects) { if (comObject != null) { Marshal.ReleaseComObject(comObject); } } } } public class AcquisitionException : Exception { public AcquisitionException(string message) : base(message) { } } public enum ImageSelectionMode { One = 0, Multiple = 1 } |
Downloadable version
{ 3 comments… read them below or add one }
Thanks - It actuall works!
I could not get the AVICap functions to recognise anything other than the base USB camera.
This sytem (WIA) allows all USB devices to be sourced and selected
Now the fun in trying to make it do what I want to do.
Thanks for the kick start
managed to get it working inVB express 2008 which is free from Microsoft.
After TurboPascal 7 this program is a real bugger to learn
Not so great /….. you are doing what mspaint does… can you bring the video and image in the same form instead of opening the default add with the camera… any how thanks for the post….
Do you know of a way to scan from default scanner without any user intervention (without showing the dialog)?