This WebCam Tutorial will guide you through connecting a webcam in Microsoft Windows and grabbing a frame from the camera so we can later
save it to a bitmap file called "Frame.bmp".
First of all this is a c++ win32 Tutorial so create an empty Win32 application.

1. Setting up some defines.

First of all we need to set up some defines that we need to connect to a webcam. If you are using Microsoft’s Visual Studio Pro edition you wont need them as they are included in Microsoft’s version of vfw.h, if you are
using something else like Code::Blocks as I am then you will need them.
I recommend storing them in a header but I will put them in the main .cpp.
They are basically just values.

We need to include two header files the first is windows.h
which is just the standard windows header. The other is vfw.h
which stands for video for windows and is where the webcam stuff is.
You will need to link to vfw32 Library in your projects linker settings.

For Code::Blocks this is done through Project -> Build Options ->
Linker Settings and click the add button and type -> vfw32.
At the same time you might as well add gdi32 as well.

For Microsofts Visual C++ Pro or Express Edition
its Project -> properties or Alt+F7.
Configuration Properties -> Linker -> Input -> Additional Dependencies
type in Vfw32.lib; and check to make sure gdi32.lib; is also there
in the dependencies.

If you are using the express Edition you will have to download the
windows sdk. Found here at ->

Click the link to download it.
And open up windows explorer and go to ->
Program Files\Microsoft SDKs\Windows\v7.0A

there you should see a bin folder, a lib folder and an include folder.
Open the include folder and select Edit -> Select All and then Edit -> Copy.

Then go to your compilers include folder typically Program Files ->
Microsoft Visual Studio 10.0-> VC
there you should see another include folder open it and paste what you have copied into it.
This will copy the Header required for this program and all other headers
which you might like to have into it.

Go back to Program Files\Microsoft SDKs\Windows\v7.0A
and open the lib folder, select Edit -> Select All and then Edit -> Copy.

Go to Program Files\ Microsoft Visual Studio 10.0\ VC
and open the lib folder and paste what you have copied into it.

This will copy a host of very good libraries one of which is called
Vfw32.lib. Which we will use in our Webcam Program.

If you are using Microsoft Visual C++ Pro or Express Edition
there is one more thing you will have to do because this code is not
a unicode build.

Go to Project -> Properties-> Configuration Properties -> General
click on Character Set and change it to use Multi-Byte Character Set.

#include <windows.h>
#include <vfw.h>

3. Procedures.

We will use 3 procedures the first is WindowProc.
The second is CreateBitmapInfoStruct which is a PBITMAPINFO
structure which contains information on color and dimension in a windows based DIB.
The third and last procedure is CreateBMPFile which creates and saves
the bitmap as a .bmp file.

There is another way to do this by enumerating all webcam drivers
on the system but for simplicity I wont be doing this in this tutorial
I may write another tutorial on how to do this at a later date.

Fourth come the Window Message Commands

1. Case 1
This connects and shows our webcam picture.
WM_CAP_SET_SCALE is set to true to enable the webcam
picture to be resized to the dimensions of our camera window.
WM_CAP_SET_PREVIEWRATE is set to 66 frames per second.
To provide a reasonable moving picture without too much demand on resources.
WM_CAP_SET_PREVIEW is set to true so a picture will be drawn on the camera window camhwnd.

3. Case 3
This grabs the frame and saves it to a .bmp file called "Frame.bmp"
WM_CAP_GRAB_FRAME does the frame grabbing this freezes the camera output so we will need to restart it later on.
WM_CAP_EDIT_COPY copies our grabbed frame to the clipboard.
Then we copy the clipboard image data to a HBITMAP object called
‘hbm’.
We then create and save the bitmap file itself using ‘hbm’ and the function call CreateBMPFile(hwnd, "Frame.bmp", pbi, hbm, hdcMem);

.

4. Case WM_DESTROY
Its important we disconnect the webcam if the user closes the window.

First up is CreateBitmapInfoStruct
which creates a PBITMAPINFO structure it takes two
arguments HWND and an HBITMAP object.

A DIB consists of two distinct parts: a BITMAPINFO structure describing the dimensions and colors of the bitmap, and an array of bytes defining the pixels of the bitmap. The bits in the array are packed together, but each scan line must be padded with zeroes to end on a LONG data-type boundary. If the height of the bitmap is positive, the bitmap is a bottom-up DIB and its origin is the lower-left corner. If the height is negative, the bitmap is a top-down DIB and its origin is the upper left corner.

A bitmap is packed when the bitmap array immediately follows the BITMAPINFO header. Packed bitmaps are referenced by a single pointer. For packed bitmaps, the biClrUsed member must be set to an even number when using the BI_RGB mode . BI_RGB means that the bitmap is uncompressed.

Secondly we use CreateBMPFile to save the bitmap
it takes 5 arguments the hwnd which owns the bitmap, the filename
in this case "Frame.bmp" a PBITMAPINFO structure which we have just went over, a HBITMAP object and a HDC, handle to device context.
First of all is pbih which is a PBITMAPINFOHEADER
this structure contains information about the dimensions and color format of a DIB.
lpBits contains the size, in bytes, of the image and we allocate some memory for it. Next up we use GetDIBits to retrieve the color table and the bits from the DIB. This function retrieves the bits of the specified compatible bitmap and copies them into a buffer as a DIB using the specified format.
In this case DIB_RGB_COLORS.

Next we create the file using CreateFile the CREATE_ALWAYS
parameter Creates a new file, always.

If the specified file exists and is writable, the function overwrites the file, the function succeeds, and last-error code is set to ERROR_ALREADY_EXISTS.

Next up is the BITMAPFILEHEADER hdr.
It is important to note that hdr.bfType has to have the ‘BM’ designator in it which is made up of 0x4d42 which is B = 0x42 and M = 0x4d.

The bfSize member specifies the size, in bytes, of the bitmap file.

hdr.bfReserved1and hdr.bfReserved2 must always be set to zero.

BfOffBits Specifies the offset, in bytes, from the BITMAPFILEHEADER structure to the bitmap bits.

Next we copy the BITMAPFILEHEADER into the .BMP file
with WriteFile
Next we copy the BITMAPINFOHEADER and RGBQUAD array into the file.
With WriteFile

Next we copy the array of color indices into the .BMP file
with WriteFile

Last of all we close the .BMP file with CloseHandle
and free the memory we allocated for lpbits

Hello,
Thank you at first for this tutorial. It worked fine for me for 2 weeks, but now i have strange bug : the preview window is black.
Cam is on and i can get some snapshots but i don't see anything in preview screen. Same script works good in VB.Net but not in c++.
I have vc++ pro Edition and Sony Vaio standard webcam. Do you have some solutions for this problem?

Hello,
Thank you at first for this tutorial. It worked fine for me for 2 weeks, but now i have strange bug : the preview window is black.
Cam is on and i can get some snapshots but i don't see anything in preview screen. Same script works good in VB.Net but not in c++.
I have vc++ pro Edition and Sony Vaio standard webcam. Do you have some solutions for this problem?

It sounds like you have a problem with your usb root hub that you have the cam connected to try the following at wikiHow