# VBForums CodeBank > CodeBank - Visual Basic .NET >  WIA (Windows Image Acquisition) WebCam Sample Project

## gigemboy

Here's a sample VB.NET 2003 project I made that shows how to capture snapshots from a webcam using WIA (Windows Image Acquisition). It detects the available device (tested with a Logitec Webcam), and allows you to grab an image. Being that it is a WIA Sample project, you have to use a WIA enabled device (usually if the device shows up in "Scanners & Cameras" in control panel, it should be WIA enabled).

The ability to use WIA, you first need to have the WIA Automation Layer, provided in "wiaaut.dll", registered. If you need this, you can download it from Microsoft here: http://www.microsoft.com/downloads/d...DisplayLang=en
You then need to add a reference to the dll if you wish to use it in a project of yours. It should already be done so in the sample project download at the end.

***Note - WIA 2.0 is only supported in Windows XP SP1 or later.

Sample project code for the procedure to get the available devices (see full code in zip file):

VB Code:
Private Sub GetDevice()
        Dim MyDevice As WIA.Device
        Dim MyDialog As New WIA.CommonDialogClass
        Try
            'shows selectdevice dialog, if only one device, It automatically selects the device
            '(not tested with two or more devices)
            '**Note - Device Type checks for VideoDeviceType, for webcams, in this sample
            MyDevice = MyDialog.ShowSelectDevice(WIA.WiaDeviceType.VideoDeviceType, False, True)
            If Not MyDevice Is Nothing Then
                'loops through device properties, only gets the ones we want to display
                For Each prop As WIA.Property In MyDevice.Properties
                    Select Case prop.Name
                        Case "Manufacturer"
                            lblMfg.Text = prop.Value.ToString
                        Case "Description"
                            lblDesc.Text = prop.Value.ToString
                        Case "Name"
                            lblName.Text = prop.Value.ToString
                        Case "WIA Version"
                            lblWIA.Text = prop.Value.ToString
                        Case "Driver Version"
                            lblDriver.Text = prop.Value.ToString
                    End Select
                Next
                'sets MyDevice form level selected device
                SelectedDevice = MyDevice
            Else
                lblName.Text = "No WIA Devices Found!"
            End If
        Catch ex As System.Exception
            MessageBox.Show("Problem! " & ex.Message, _
                  "Problem Loading Device", MessageBoxButtons.OK, MessageBoxIcon.Warning, _
                  MessageBoxDefaultButton.Button1, MessageBoxOptions.DefaultDesktopOnly)
            lblName.Text = "No WIA Devices Found!"
        End Try
    End Sub
Sample project code to grab the picture from the device (see full code in zip file):

VB Code:
Private Sub btnGrab_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnGrab.Click
        Dim item As WIA.Item
        Try
            'executes the device's TakePicture command
            item = SelectedDevice.ExecuteCommand(WIA.CommandID.wiaCommandTakePicture)
        Catch ex As System.Exception
            MessageBox.Show("Problem Taking Picture. Please make sure that the camera" & _
                          "is plugged in and is not in use by another application. " & vbCrLf & _
                          "Extra Info:" & ex.Message, "Problem Grabbing Picture", _
                          MessageBoxButtons.OK, MessageBoxIcon.Warning, MessageBoxDefaultButton.Button1, _
                          MessageBoxOptions.DefaultDesktopOnly)
            Exit Sub
        End Try
        Dim jpegGuid As String
        'retrieves jpegKey from registry, used in getting JPEG format of pic, can be hard coded
        Dim jpegKey As Microsoft.Win32.RegistryKey = _
                 Microsoft.Win32.Registry.ClassesRoot.OpenSubKey("" & _
                 "CLSID\{D2923B86-15F1-46FF-A19A-DE825F919576}\SupportedExtension\.jpg")
        jpegGuid = CType(jpegKey.GetValue("FormatGUID"), String)
        'loops through available formats for the captured item, looking for the JPG format
        For Each format As String In item.Formats
            If (format = jpegGuid) Then
                'transfers image to an imagefile object
                Dim imagefile As WIA.ImageFile = CType(item.Transfer(format), WIA.ImageFile)
                Dim Counter As Integer 'counter in loop appended to filename 
                Dim LoopAgain As Boolean = True
                'searches directory, gets next available picture name
                Do Until LoopAgain = False
                    Dim Filename As String = SavePath & "\" & txtPrefix.Text & Counter.ToString & ".jpg"
                    'if file doesnt exist, save the file
                    If Not System.IO.File.Exists(Filename) Then
                        SavedFilePath = Filename
                        imagefile.SaveFile(Filename) 'saves file to disk
                        lblCapName.Text = FormatPath(Filename)
                        lblImageName.Text = txtPrefix.Text & Counter.ToString & ".jpg"
                        picCap.Image = Image.FromFile(Filename) 'loads captured file to picturebox
                        LoopAgain = False
                    End If
                    Counter = Counter + 1
                Loop
            End If
        Next
        If grpSaved.Enabled = False Then
            grpSaved.Enabled = True
        End If
End Sub
The code automatically saves the picture to a new filename, so you can grab multiple captures one after another.

The project so far is only for webcams, but can be extended to do similar things with digital cameras, camcorders, basically any supported WIA device.

----------


## gigemboy

I was trying to modify this project to add a video preview option so you can see the image before capturing, but there seems to be a problem with passing the window handle needed when using the WIAVideo 1.0 Type Library.. its all explained in this post:

http://www.vbforums.com/showthread.php?t=379485

If anyone cares to take a stab at it, feel free to respond there...

----------


## Mr.No

By the way WIA works on Windows 2000 also.

----------


## gigemboy

> By the way WIA works on Windows 2000 also.


Correct, but the 2.0 Library referenced in the project is only supported on Windows XP (at least in their documentation). Haven't tested it on other O/S'es

"Windows Image Acquisition Automation Library v2.0 is only supported on Windows XP with Service Pack 1 installed."
http://www.microsoft.com/downloads/d...DisplayLang=en

----------


## VBDT

Hi gigemboy and thanks for this great code. I just want to say that there is an another way to get the image without saving it in to a file and then loading it into picCap control. I think this might be a little faster than saving and loading from the file.

VB Code:
Dim f As MemoryStream
f = New MemoryStream(CType(myImageFile.FileData.BinaryData, Byte()))
picCap.Image = Image.FromStream(f)
Just a little addition.

----------


## gigemboy

Well thx for posting that. Its been a while since I had messed with the code and I forgot I was even doing that. If I would have remembered I would have been ashamed  :Smilie:  hehe Learned a lot since then...

----------


## kwaltman

Your code works perfectly. Thank you very much.   :Thumb:  

I do have one question. My webcam takes about 3-4 to self adjust the brightness before the picture is good. Right now the pictures are coming out very dark when I snap the pics using the code. Is there anyway in the code to activate the cam, wait a couple of seconds, and then snap the pic?

----------


## Dylan_C

Gig, this is a great submission and a killer example. Keep up the good work!

----------


## deadbeatclub

Thanks gigemboy, that code is EXACTLY what I needed. I have just a high level understanding of VB (I'm a C++ nerd) and I'm using it because the WIA automation layer targets it. Here's my challenge: I want to use the webcam preview and take picture features in our C++ product. We have a common DLL interface and with CE I write a C++ DLL for each camera we support. Now I can create a VB6 form or ActiveX control for WIA webcams, but I'd want to wrap it with C++ so it can drop seamlessly into our product. Anyone know if it's possible or just a pipe dream? And if it's possible how I'd go about it? I've tried the ActiveX route, and although I can drop the control on a VB6 form, I get errors when I try to use it with a C++ dialog ("not implemented" - E_NOTIMPL). Thanks in advance for any help! (Oops! I noticed this is a .NET forum - I'll post the same question in another, more appropriate place too...)

----------


## lalala

I did'nt work with me. I also need to know how do I know if the selected device is being used by another application. I dont want to see the select device window that appear if another application is using the webcam. What can I do for this window not to appear (sorry, my english is not perfect). Hope someone can help me!!!

----------


## candy78

hi i have a problem i have a program that take that picture but when this found the webcam is busy they program show me a control window for looking for a new webcam i like to know how i can to know if the webcam is in use the program do nothing 
thankyou so much

----------


## alisanjaya

how to change the webcam capture resolutions in video preview mode ?
i'm using logitech webcam, that only can capture 320 x 240 of resolutions

how to change the video preview to 640 x 480 in visual basic?

with logitech software that came with the webcam, the video preview can be 1024 x 768.

thanks

----------


## wamberto

Hi, i also have the same problem.
Can someone hel please ???

----------


## skeith

This is excellent stuff.  I am interested in using the MemoryStream functionality but I am missing something.  How is MyImageFile set?  How do you reference a fram in the video stream.

Much appreciated.

----------


## kul2bme

Kudos to you gigemboy. i tried the code as is and it worked right of the box. I made a couple of mods for VB.NET 2008 project and have the solution I needed. Thanks again.

Camera class for all to enjoy.

vb Code:
Imports System
Imports System.IO
 Public Class clsCamera
    Private _SelectedDevice As WIA.Device
    Private _SavePath As String
    Private _DeviceName As String
    Private _DeviceDesc As String
    Private _DeviceMfg As String
    Private _DeviceWIAVersion As String
    Private _DeviceDriver As String
    Private _CameraMemoryStream As MemoryStream
     Public Property SelectedDevice() As WIA.Device
        Get
            Return _SelectedDevice
         End Get
        Set(ByVal value As WIA.Device)
            _SelectedDevice = value
         End Set
    End Property
     Public Property SavePath() As String
        Get
            Return _SavePath
         End Get
        Set(ByVal value As String)
            _SavePath = value
         End Set
    End Property
     Public Property DeviceName() As String
        Get
            Return _DeviceName
         End Get
        Set(ByVal value As String)
            _DeviceName = value
         End Set
    End Property
     Public Property DeviceMfg() As String
        Get
            Return _DeviceMfg
         End Get
        Set(ByVal value As String)
            _DeviceMfg = value
         End Set
    End Property
     Public Property DeviceDesc() As String
        Get
            Return _DeviceDesc
         End Get
        Set(ByVal value As String)
            _DeviceDesc = value
         End Set
    End Property
     Public Property DeviceWIAVersion() As String
        Get
            Return _DeviceWIAVersion
         End Get
        Set(ByVal value As String)
            _DeviceWIAVersion = value
         End Set
    End Property
     Public Property DeviceDriver() As String
        Get
            Return _DeviceDriver
         End Get
        Set(ByVal value As String)
            _DeviceDriver = value
         End Set
    End Property
     Public Property CameraMemoryStream() As MemoryStream
        Get
            Return _CameraMemoryStream
         End Get
        Set(ByVal value As MemoryStream)
            _CameraMemoryStream = value
         End Set
    End Property
    Public Function GetDevice() As Boolean
        Dim MyDevice As WIA.Device
        Dim MyDialog As New WIA.CommonDialogClass
        Try
            'shows selectdevice dialog, if only one device, It automatically selects the device
            '(not tested with two or more devices)
            '**Note - Device Type checks for VideoDeviceType, for webcams, in this sample
            MyDevice = MyDialog.ShowSelectDevice(WIA.WiaDeviceType.VideoDeviceType, False, True)
            If Not MyDevice Is Nothing Then
                'loops through device properties, only gets the ones we want to display
                For Each prop As WIA.Property In MyDevice.Properties
                    Select Case prop.Name
                        Case "Manufacturer"
                            DeviceMfg = prop.Value.ToString
                        Case "Description"
                            DeviceDesc = prop.Value.ToString
                        Case "Name"
                            DeviceName = prop.Value.ToString
                        Case "WIA Version"
                            DeviceWIAVersion = prop.Value.ToString
                        Case "Driver Version"
                            DeviceDriver = prop.Value.ToString
                    End Select
                Next
                'sets MyDevice public selected device
                SelectedDevice = MyDevice
            Else
                DeviceName = "No WIA Devices Found!"
            End If
            GetDevice = True
        Catch ex As System.Exception
            If ex.Message <> "Exception from HRESULT: 0x80210015" Then
                 MessageBox.Show("Problem! " & ex.Message, "Problem Loading Device", MessageBoxButtons.OK, MessageBoxIcon.Warning, MessageBoxDefaultButton.Button1, MessageBoxOptions.DefaultDesktopOnly)
            End If
            DeviceName = "No WIA Devices Found!"
        End Try
    End Function
     Public Function GrabPic() As Boolean
        Dim item As WIA.Item
        Try
            'executes the device's TakePicture command
            item = SelectedDevice.ExecuteCommand(WIA.CommandID.wiaCommandTakePicture)
        Catch ex As System.Exception
            MessageBox.Show("Problem Taking Picture. Please make sure that the camera is plugged in and is not in use by another application. " & vbCrLf & "Extra Info:" & ex.Message, "Problem Grabbing Picture", MessageBoxButtons.OK, MessageBoxIcon.Warning, MessageBoxDefaultButton.Button1, MessageBoxOptions.DefaultDesktopOnly)
            Exit Function
        End Try
        Dim jpegGuid As String
        'retrieves jpegKey from registry, used in saving JPEG
        Dim jpegKey As Microsoft.Win32.RegistryKey = Microsoft.Win32.Registry.ClassesRoot.OpenSubKey("CLSID\{D2923B86-15F1-46FF-A19A-DE825F919576}\SupportedExtension\.jpg")
        jpegGuid = CType(jpegKey.GetValue("FormatGUID"), String)
        'loops through available formats for the captured item, looking for the JPG format
        For Each format As String In item.Formats
            If (format = jpegGuid) Then
                'transfers image to an imagefile object
                Dim imagefile As WIA.ImageFile = CType(item.Transfer(format), WIA.ImageFile)
                Dim Counter As Integer = 1 'counter in loop appended to filename 
                Dim LoopAgain As Boolean = True
                'searches directory, gets next available picture name
                Do Until LoopAgain = False
                    Dim Filename As String = SavePath & Counter.ToString & ".jpg"
                    'if file doesnt exist, save the file
                    If Not System.IO.File.Exists(Filename) Then
                        imagefile.SaveFile(Filename) 'saves file to disk
                        LoopAgain = False
                    End If
                    CameraMemoryStream = New MemoryStream(CType(imagefile.FileData.BinaryData, Byte()))
                    Counter = Counter + 1
                    GrabPic = True
                Loop
            End If
        Next
        
    End Function
     Public Sub New()
        SavePath = Application.LocalUserAppDataPath & "\Card Picture Files\"
    End Sub
End Class

----------


## skeith

Thanks from me also.  I got the code to work as well.  I have one question however.  It takes about 5 seconds for the "takePicture" function to execute.  How do I get the time down below 1 second?  Is it the camera, the WIA object, ????   What do I need to improve the time?!!  


thanks in advance.

----------


## mnavas

Same problem takes 5 sec in the "take picture"... How to get it below 1sec?

----------


## CXXXV

This is good stuff. However, I've been tring for a whole day to make this work. 

No matter what I try it simply will not recognize that there are cameras atached to the PC. The Control Panel dialog shows the cameras. The device manager shows the cameras.

I am running XPPro-SP1. Any suggestions.

----------


## j0e2

i'm agree with my top..

START DESPERATELY

----------


## RossWaddell

Has anyone determined if you can use "Windows® Image Acquisition Automation Library v2.0 Tool: Image acquisition and manipulation component for VB and scripting" in a VB6 app and have it run on Vista or Windows 7? I've created an app that is wholly dependent on WIA and I've had to put a restriction on the install that the computer must be running Windows XP SP1 or  later (but not Vista or 7). I really want to remove that restriction, but I don't have access to a machine with either of those OSs.

----------


## fabio.bozzo

Hi gigemboy and congratulations! Very remarkable post!
You helped me starting with WIA automation SDK.
I'm using vb.NET 2010 and trying to do this:
I have got 5 Nikon cameras, USB attached to my pc. I want them to grab a picture simultaneously. I don't want to do it in a 'serial way', waiting for the previous to finish executeCommand().
So, my first approach was that:



```
Private Class PhotoTaker
        Public fotocamera As WIA.Device
        Public Sub grabPicture()
            fotocamera.ExecuteCommand(WIA.CommandID.wiaCommandTakePicture)
        End Sub
End Class

    Private Sub ProvaThreadToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ProvaThreadToolStripMenuItem.Click
        For Each device As WIA.DeviceInfo In deviceManager.DeviceInfos
            Dim nuovaFoto As New PhotoTaker()
            nuovaFoto.fotocamera = device.Connect
            Dim thread As New Thread(AddressOf nuovaFoto.grabPicture)
            thread.IsBackground = True
            thread.Start()
        Next
    End Sub
```

Very simple isn't it? But.... that doesn't work!! They still shoot one after the other!
The funny part of the story is that:
if I call an external exe, who only grab the picture from the camera with executeCommand() ..... it works! They shoot at the same time!  :Frown: 
What's wrong in my threads??  

Thanks a lot!

----------


## eaglecmt

HELLO GIGEMBOY

I would like to thank you for this code it's very useful form, But I have question :Confused:  HOW CAN I MODIFY THIS CODE TO WORK WITH SCANNER? I'm still new in WIA application.

Thank you  :wave:

----------


## JustinW

First off, thanks so much for the codes and sample project. It's really appreciated!

I've downloaded the example and ran it from my XP machine connected to a LogiTech Orbit WebCam. It worked 100%.

However, when I ran the sample in my Windows 7 (64-bit) machine (exact same camera). The codes failed and could not find the device.  I would really appreciate if you can show me the light as to what I need to change in order for this to work with Windows 7 (64-bit). Is there a new version of WIA that is needed (I didn't find any mention of that in msdn)?  Are there other libraries I need to reference?

Thanks so much for you help!

Justin

----------


## Cruzh

How to Use WIA on Windows 7, because it's not RUn,,,???

----------


## [gja]

Hello gigemboy,

how to modify this code to start 2 camera and capture image from both camera in one button..

thank you.

----------


## moti barski

how many image captures per minute with the WIA ?

----------


## richter

Good Day... God Bless!!!

Hello Gigemboy,

Can you help me provide source code for MS Access for the Webcam Capture.
Im Ms Access user...

Thank you.

----------


## tuxalot

Hi Richter,

I've got image capture working in MS Access with a USB connected WIA capable camera. PM me and I will send the code (would post here but it's off topic). What it does NOT do is provide image preview, hence me lurking here.

Tux

----------


## Ben321

I have a general WIA quesion. When I use Photoshop or other software with a WIA interface for cameras I find that the preview images that are saved when you press the "capture" button stay there between uses, even between closing and reopening Photoshop, even between different programs! Where does Windows store these preview images? I can't find any documentation for this little "feature" at all! What if I want to clear the WIA preview image cache (or whatever they call it)? How do I do that?

----------


## johnvpr

I'm trying in vs2010, but I get exeption HRESULT: 0x80210015 on starting and each time I try to select a device a trust WB 3500T on win7 32bit

----------


## swaj

> I'm trying in vs2010, but I get exeption HRESULT: 0x80210015 on starting and each time I try to select a device a trust WB 3500T on win7 32bit


Hi, i also have the same problem.
Can someone help please ???

my system : win XP SP3 32bit :vs2010 Ultimate
naw not scnner Device Connect

----------


## mserrano@sc-services

The same for me... W10 + VB2010 Exp + Canon MX360 scanner and/or build-in "USB2.0 UVC HD WebCam"

----------

