EDIT (20-11-2011) : Since posting this, I have created a new DirectShow command line image grabber called CommandCam, which I recommend you use instead of this one. It’s also completely free. Get CommandCam here (binary download and source code available).
Earlier today, I was looking for a command line image grabber for Windows to use with a webcam in a batch file. To my amazement, I simply could not find one that worked for me, so I’ve hacked together my own simple one in C using Microsoft’s venerable Video for Windows (VFW) API. Of course, there’s probably a “better” way of doing this, but this program is at least reasonably concise and to the point – basically, it’s what I needed. Thankfully, it’s much shorter than any of the video capture programs I ever wrote using DirectShow. The error checking is rudimentary to say the least – you might get an error message if something goes wrong.
Acknowledgement: My Win32 programming was never very good, but it’s extremely rusty right now, so theForger’s Win32 API Tutorial proved absolutely indispensible when I was writing this program. It’s a wonderful resource and is definitely my favourite Win32 programming guide – many thanks to theForger!
Here’s the executable file:
snapz.exe (24KB, date: 5-4-2011)
To use it, open a command window, move to the directory where snapz.exe
is saved and simply type snapz
. The program will open the default video capture device (e.g. a webcam) and grab a single snapshot at 640×480 resolution. The image will be saved to a device independent bitmap (DIB) file called snapz.dib
in the same directory. This file format is uncompressed, so the file will be almost 1MB in size. You can convert it to a different format using another graphics program if you wish. I’m planning to use ImageMagick for that purpose in the batch file I’ll be using snapz in.
Here’s a screenshot of my command window. Note that the file snapz.dib
appeared in the directory when I ran snapz.exe
.
Here’s the image it captured (my arm, kettle, toaster):
Here’s the snapz code:
snapz.c (4KB, date: 5-4-2011)
I compiled it using gcc (MinGW version 5.1.4). The command to compile it is:
gcc -o snapz.exe snapz.c -lvfw32
If this turns out to be useful to you, please leave a comment to let me know.
Here’s the complete code:
// // snapz.exe - a command line cam image grabber // Written by Ted Burke, Last updated 5-4-2011 // ted.burke@dit.ie, batchloaf.wordpress.com // // To compile with MinGW: // gcc -o snapz.exe snapz.c -lvfw32 // #include <windows.h> #include <vfw.h> #include <stdio.h> // Window handles HWND hWnd; HWND hWndCap; int capture_w = 640; int capture_h = 480; int capture_device = 0; // default capture device int time_delay = 0; // delay in ms before snapshot int preview_video = 0; // Don't show on screen // Message handling function LRESULT CALLBACK WndProc( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) { switch(msg) { case WM_TIMER: // Save DIB snapshot, then exit from program capGrabFrame(hWndCap); capFileSaveDIB (hWndCap, "snapz.dib"); DestroyWindow(hWnd); break; case WM_CLOSE: DestroyWindow(hWnd); break; case WM_DESTROY: PostQuitMessage(0); break; default: return DefWindowProc(hWnd, msg, wParam, lParam); } return 0; } int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { // Register window class WNDCLASSEX wc; wc.cbSize = sizeof(WNDCLASSEX); wc.style = 0; wc.lpfnWndProc = WndProc; wc.cbClsExtra = 0; wc.cbWndExtra = 0; wc.hInstance = hInstance; wc.hIcon = LoadIcon(NULL, IDI_APPLICATION); wc.hCursor = LoadCursor(NULL, IDC_ARROW); wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1); wc.lpszMenuName = NULL; wc.lpszClassName = "snapzWindowClass"; wc.hIconSm = LoadIcon(NULL, IDI_APPLICATION); if(!RegisterClassEx(&wc)) fprintf(stderr, "Window Registration Failed!"); // Create main window hWnd = CreateWindowEx( WS_EX_CLIENTEDGE, "snapzWindowClass", "snapz", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, capture_w + 100, capture_h + 100, NULL, NULL, hInstance, NULL); if (hWnd == NULL) fprintf(stderr, "Couldn't create main window."); // Create capture window hWndCap = capCreateCaptureWindow( NULL, WS_CHILD, 0, 0, capture_w, capture_h, hWnd, 0); if (hWndCap == NULL) fprintf(stderr, "Couldn't create capture window."); // Connect to capture driver and set resolution capDriverConnect(hWndCap, capture_device); DWORD dwSize = capGetVideoFormatSize(hWndCap); LPBITMAPINFO lpbi = (LPBITMAPINFO)malloc(dwSize); capGetVideoFormat(hWndCap, lpbi, dwSize); lpbi->bmiHeader.biWidth = capture_w; lpbi->bmiHeader.biHeight = capture_h; capSetVideoFormat(hWndCap, lpbi, dwSize); free(lpbi); // Initialise and start video preview if (preview_video > 0) { // Set up video preview capPreviewRate(hWndCap, 1); // rate in ms capPreview(hWndCap, TRUE); ShowWindow(hWndCap, SW_SHOW); //Show main window ShowWindow(hWnd, nCmdShow); UpdateWindow(hWnd); } // Set timer to trigger snapshot SetTimer(hWnd, 1, time_delay, NULL); // Message loop MSG msg; while(GetMessage(&msg, NULL, 0, 0) > 0) { TranslateMessage(&msg); DispatchMessage(&msg); } // Tidy up video capture stuff KillTimer(hWnd, 1); capPreview(hWndCap, FALSE); capDriverDisconnect(hWndCap); if (hWndCap) DestroyWindow(hWndCap); return msg.wParam; }
nice coding man, this is what im looking for dude!
btw, need ur little help again, do u mind if i add u on msn or ym? leave ur email or add me at kiraichi_gsx@hotmail.com or kiraichi_gsx@yahoo.com
thanks batchloaf!
Hi Kiraichi, thanks for your comment. I’m not on yahoo or msn and to be honest, I tend to be very busy. However, if there’s something simple you’d like added or changed in the program, just leave a comment here and I’ll see whether I can implement it. Thanks again.
Sir,
Is it posible to have imagecapture for more than one webcam attached to machine with your program, I dont have the compilation env .
thanks
Hi Rishipal,
Do you mean that you want to simultaneously snap images from two or more cameras, or do you want to simply select one of a number of cameras that are connected to the machine? Selecting one camera from a number would be a simple change to make. Capturing images from more than one camera simultaneously is a bit more complicated, but I suppose I could give it a shot if that’s what you’re trying to do.
Can you please explain in more detail what you need to do? I won’t get a chance to do anything about it for at least a couple of days, but I can try to revise the program during next week if it’s something reasonably straightforward. If so, I can post a revised compiled version.
Thanks,
Batchloaf
Good day. First off, I would like to say that your software is just what I was looking for and I would like to thank you for that. However, why doesn’t the software close? It just continues on running. Any ideas would be nice.
Best Regards,
James Tan
James, thanks for reporting the problem with the program not closing. I’d like to solve it, but unfortunately I can’t reproduce it on my computer. Could you please provide some further details? For example, which version of Windows you are running and maybe even a screen shot of the program running (and not closing) in the command window (click in the command window, press Alt-PrintScreen to copy an image of it to the clipboard, then paste it into MS Paint or something similar). There are a couple of thing I can try changing to see if they solve the problem, but I might need to ask you to try out the modified versions on your computer to tell me if they work. I would really appreciate your help in tracking down and solving this problem.
Thanks for your reply
Sir,
There are 5 webcam attached to one PC and for my phd project I have to captur Imag from one webcam at one time depending upon the hardware event I have to do this through program and then do the measurement work using the captured image. I work in labview and have done the interfacing with hardware and the image processing work and tested it using the manually captured images. Your program is the wright thing for getting the images programatically by executing the command on commandline from labview env. But the problem I am facing is I am not getting able to select the required webcam on the command line along with the snapz command.
I thought the simplest way could be to compile 5 diffrent versions of your program say snapz1.exe to snapz5.exe by compiling each version by setting the “capture_device” parameter value to 0,1,2,3,4. I tried to do this but I could not succed because I know little about C++ and also because I am trying this with VC++ version6 as I dont have gcc env.
It could be a great help for me and people like me who wants to use your program if the facility to select the required webcam is provided as command line parameters.
thanks
Hi Rishipal. Unfortunately, it seems that multiple camera image capture using snapz may not be possible after all. Please see this post where I discuss the reason.
Thanks for open sourcing this handy script! Just what I was looking for to capture frames from a USB HP webcam.
Paul, thanks for your comment. I’m very glad to hear that you found it useful.
Thanks for your reply
Sir,
I finally compiled your script with VC++ and reached to the same conclusion as you have stated in your post, but certainly the snapz code is the best way to capture the image from command line .
Finally I succeeded in capturing image from multiple cameras from command line using the autoit script programming.
with regards
Rishipal yadav
Hi Rishipal. Ok, well thanks very much for giving it a try. I’m delighted to hear that you found a solution to your problem anyway. I’m now having a go at rewriting snapz using DirectShow, so if you need a command line solution for multi-camera image capture again in the future, please do check back here. Best of luck in your research!
Handy program. I am running in to a problem though, I can only seem to capture one picture and then something “breaks”. . On my xp machine it just stops working no pop ups, even a full shutdown doesnt help. I am guessing something in the VFW on my machines may not be resetting after the picture is taken.
Hi Lawrence,
Wow, that’s strange! I’m guessing that the problem you’re having is related to a driver issue on your machine – probably related to opening the camera device via VFW rather than DirectShow. Admittedly, that’s just speculation really, but I don’t think there’s anything unusual about how snapz opens and closes the VFW device. I would be curious to know if another (tried and tested) VFW-based program works correctly on your machine – do you happen to know if this is the case?
Anyway, if you’re still looking for a program to do what snapz does, please check back over the nest few days – I should be posting a DirectShow-based version of snapz, which will hopefully be better behaved on a wider variety of machines.
Thanks for the feedback!
A DShow based version would be great. You are most likely right on the driver issue. I have tried some VFW capture programs and they do work but they all require a video window displayed on the screen to capture. The reason i wanted this was to be able to snap a picture of a thief that had stolen a clients laptop for the police.
Hi, it’s exactly what I was searching for. Unfortunately, it only works when I connect a webcam through USB. With my built-in webcam, it asks to choose a device and when I choose my webcam an empty image is stored. Anyone else with the same problem?
Hi Jef, thanks for the feedback and sorry for the delay in replying. I’ve been up to my eyes for the last few weeks, but once things settle down I’m planning to have a go at rewriting this application “properly” using DirectX, which should hopefully work with a wider variety of cameras. Please keep an eye out for the updated version – I’d appreciate knowing if it works for you.
Hi, thanks for replying. In the meantime I figured out it does work with my built-in webcam each first time I run it after restart, and afterwards it won’t. Strange, but actually it’s enough for me, because I wanted it to take a snapshot on startup and put it in my dropbox so I could see my laptop’s thief his face :-).
Ha ha, what an interesting application!
It sounds like the problem you were having is related to the fact that snapz accesses whatever camera it uses through the older Video For Windows (VFW) API. Windows does contain an adapter driver which can “wrap” a newer DirectShow driver allowing a camera that does not have a VFW driver to be accessed via that API. Anyway, I’m glad you found a solution!
Thanks! This is all I needed, but its surprising how difficult it was to get something to do this simple task. As far as I can tell it works perfectly on my computer with my default/built in webcam.
Thanks Wes, I’m glad to hear that it’s working for you!
Hey! Thanks for the Snapz program!
However, I am facing some issues too.
I can run snapz successfully for the first time, then when i try to run it again, a box appears and asks me to select the webcam (i only have 1).
It then saves an empty snapz.dib to the computer.
It seems that there is a problem with the VFW stuff.
I was trying out simple capturing of webcam shots with Java’s JMF too. The same thing happened.
First run = ok. Onwards = failures.
Hope you can release the direct show version asap! It would be perfect if it works 100%.
Thanks for the hard work! Keep it up!
-A Snapz fan
Hi Snapz Fan, thanks for your comment. Sorry it didn’t appear straight away – I though I had approved it, but I just noticed that it was still in the “pending approval” list, so I must have clicked the wrong thing. Anyway, hopefully the forthcoming DirectShow version will solve the problem you’re having. If you get a chance to try it out when I post it here, I’d be interested to hear whether it works for you.
Great work, man waited DirectShow version good luck,
Hi,
Unfortunately, the snapz.exe program does not work for me. It creates a .dib file but it’s empty.
I tried putting it into Visual Studio and it compiled and did the same thing. But in debug it gave me a memory allocation error on free(lpbi);
It never gets to the selection of webcam in debug, although in the compiled version it does, thanks,
Thanks for the feedback Dmitry. I’ll be posting a DirectShow version of the program soon, which will hopefully solve the problem you’re experiencing.
In case anyone’s waiting for it, I’ve now posted a DirectShow command line webcam image grabber.
😀
Hi Batchloaf, I don’t know if you are still checking this board, but I was wondering if you knew of a way to set a built-in HP webcam to start recording at a specific time? I think a neighbor or someone has been letting themselves in recently and have narrowed down a time, but I am at work… I could start recording in the morning, but want to avoid the blank hours of tape as well as the extra GB’s that would surely take up.
Any help would be greatly appreciated.
Thanks
Hi Chris. If you want to record video when someone is there, I think there are software tools that record only whenever something moves in front of the camera. They’re designed for just this sort of security application. However, I haven’t used them, so I’m afraid I can’t recommend a specific one. If you google “motion sensing video capture” or something like that, I’m sure you’ll find something like what I mean.
CommandCam only captures still images, so it probably isn’t suitable for what you want. However, it does have an option to delay for a specified period of time before snapping an image. The latest version of CommandCam is here:
https://batchloaf.wordpress.com/commandcam/
Also, I have another program called RobotEyez, which can take a series of snapshots. It might do the trick. Here’s the link:
https://batchloaf.wordpress.com/2011/11/27/ultra-simple-machine-vision-in-c-with-roboteyes/
Thanks Batchloaf, I was able to find several free motion sensor programs to try. I will try a couple and post back which works the best. Appreciate the tip. Keep up the good work!
Hi Chris. You’re very welcome. Best of luck getting it working!
Just wanted to give you an update. I found a great program called iSpy. It’s free and works great!
I do recommend it.
Thanks again for the assist in finding this.
Take care.
Chris
Thanks Chris, I’ll keep that in mind since I’m sure it will be of use to other people who are trying to use CommandCam for a similar purpose.
Thanks for sharing this. This can be a great help for me.
i want to pass the path and file name where i want to save the image file.
how can i do this?
Please comment asap.
Hi Avinash,
The easiest way to do this is to use my other webcam snapshot program, CommandCam. With CommandCam, you can do this:
The filename can include a full path, or it can just be a filename to save in the current folder.
If you are determined to use snapz for some reason, you can just let it save to the default filename, then move the file to the desired location. Something like this will do it:
Can you give me a sound recorder
Hi “Nothing”,
Do you mean you’re looking for a command line audio recorder? If so, then perhaps Sox can do what you need? I haven’t used it for a couple of years, but it’s free and open source and really flexible. They describe it as the “Swiss Army knife of sound processing programs”, which is pretty accurate.
Ted
I mean something like a sound recorder in .exe which secretly records your voice after you open it and save the result in a .wav file in your com. I don’t want those which need installation. Just the snapz.exe you posted.
I mean something like snapz.exe
I don’t have any plans to develop a command line audio recorder. It would be straightforward enough to create one, but it would take a little time and unfortunately I’m too busy with other work to do it. However, I suspect you can find a “portable” version of Sox which will do exactly what you need. I just googled “portable sox” and found this:
http://www.softpedia.com/get/PORTABLE-SOFTWARE/Multimedia/Audio/SoX-Portable.shtml
I don’t know anything about that, but it looks like a reasonable place to start your investigation.
HI,
I am using snapz.exe, while capturing the images, the images are capturing in background,is any possible way to see the image streaming in Foreground.
Hi Ram,
I suggest that you try my other program, CommandCam, which is similar to snapz, but it provides a preview option. Here’s the link:
https://batchloaf.wordpress.com/commandcam/
Ted
Thanks for ur Fast Reply, I already used Commandcam still we are facing same problem.
Exactly our requirement is to See the image(While Taking the Snap From .exe,)
Hi Ram,
When you use the preview option in CommandCam, you should be able to see the image onscreen before it is snapped. Is that working for you?
If you only want the image too be snapped when the user (who is watching the preview) presses a button or something, that is a different problem and it’s not really what CommandCam is intended for. There are lots of other programs that do that (show a preview then take a snapshot when you click a button).
Ted
how to check the preview option in CommandCam, i am unable to see that one
You just run it with a command like this:
Sometimes, the preview takes a few seconds to appear, so you may need to add something like:
That would add a 5 second (5000ms) delay before the snapshot is taken.
As I mentioned before, if you’re trying to take a snapshot interactively (i.e. when you manually press a key or click a button), CommandCam probably isn’t the best program for your purpose since it’s not designed for this purpose. CommandCam is designed for automatic snapshots without human interaction. There are other programs that provide this functionality (click a button to take a picture).
Thanks for the simple and easy code. I was able to change the resolution to 1920×1080 to match my new webcam and recompile the code. My first snapz produced an all black image for some reason. But the second turned out OK. I intend to use my webcam as a remote weather camera and need a simple interface that I can use via a dial-up PPP link. Your code will do the trick!
Thanks again!
John L
Thanks John, I’m delighted you found it useful!
hi batchloaf, u have done a great job,
even i want to write a program like this in linux(UBUNTU) to automate the process of accessing the webcam and streaming it using apache webserver.. can u give me some clue where to look for. i have tried a lot with no success
Hi Sumit,
There are definitely several free software tools available that do this in Linux. Try looking up “streamer”, “mplayer”, and “VLC”. I’m sure it’s possible with at least one of those, although it might take some messing around with command line options to find the exact command you need.
I’ll have a look myself later on to see how I did this before.
You can write a program yourself to read from the camera too, although I don’t think that will be necessary. If you decide to try this, look up Video4Linux and Video4Linux2. You should find some useful information. Try doing some simple video capture in VLC first though so that you can work out what device name your camera is using.
Ted
thanks for replying ..
well i have already tried motion and webcam-server and motion seems to work fine but the webcam-server doesn’t work fine and gives some error regarding ioctl and vidio macros and my webcam is /dev/video0 on my mac. motion is a very big program while i need only basic functionality as per my need so was thinking about writing program on my own. being a beginner in linux please suggest me good resources related.
Sumit
If you really want to write your own program, you can find the V4L2 (Video for Linux API) documentation here:
http://linuxtv.org/downloads/v4l-dvb-apis/
However, please be aware that it will be complicated! Probably a good place to start is with a sample program. You can find one here (download the tar.gz file for version 0.4.1):
http://alumnos.elo.utfsm.cl/~yanez/video-for-linux-2-sample-programs/
Personally, I think it would be much easier to find one of the existing programs that is out there and work out how to use it. For example, you could use Streamer, which I mentioned in my previous reply. I believe mplayer can also be used to take snapshots from the command line.
Whatever you decide to do, I think you should definitely begin by opening your camera for video capture in VLC as I suggested above. That way you will be sure what device name to use with other programs (including ones you have written). It would be absolutely crazy to try writing your own program without at least confirming that you can open the camera from VLC or some other existing program. There is no guarantee that the device name will be the same as it is in MacOS.
Ted
hey thanks so much for helping me out.
basically i m doing a project that involves hosting a web server(site) which should provide the user with a link that redirects him to the video feed from a webcam or usb cam. i know i have to use php for the site part but how do i embed the stream on that page? totally clueless…
Thanks for this tool! But is there a way to change it so that it doesn’t replace that file, but rather create a new one for instance “snapz.dib” and then “snapz2.dib” etc?
Hi Adriaan,
It would certainly be possible to do this using a simple batch file with a loop that runs snapz repeatedly and renames each output file. However, what would be even easier would be to use my other similar program, RobotEyez, which allows saving to multiple numbered files:
https://batchloaf.wordpress.com/2011/11/27/ultra-simple-machine-vision-in-c-with-roboteyes/
Instructions for using RobotEyez are included on that page.
Regards,
Ted
Great work!
Thanks!
it would be nice if it save image file randomly other than replacing.. like image01, image02
Hi Shiuth,
I have another free program called RobotEyez which does exactly what you’re looking for:
https://batchloaf.wordpress.com/2011/11/27/ultra-simple-machine-vision-in-c-with-roboteyes/
Regards,
Ted
hello, is there a way to make batch file which captures screen portion to same file after certain time interval?
WOW just what I was searching for. Came here
by searching for canon fd lens
Great, glad you found it useful!
How to use it in remote desktop situations. Maybe you can help…?
Nice program. Adding a date/time stamp into the file name would make it even more useful.
Thanks Fadi, I’ll make a note of that for whenever I get around to doing an update.
Ted
Please make an update soon!
Thank you so much for the download, the source and the explanation.
That was exactly what i spect when i search “get webcam image from webcam windows”.
The sources plus the app. THX!
You’re welcome m3nda!
Ted
Well done! Thank you so much for sharing your solution. This is just what I needed. Many thanks!
You’re welcome!
Ted
hi sir batchloaf im trying to create a voters registration form in ms access
i want to put a camera button in my registration form and directly save to my database after it captures image .. but i dont know what code to use .. can you help me about that ? if not its ok 🙂
i just think i can use your snapz.exe but i dont know how ..
Hi Anjo,
Sorry, but it’s quite a few years since I’ve used MS Access, so I can’t remember much about it. I’m sure this is possible, but I’m not sure where you would start exactly.
After I posted this, I wrote a couple more image grabber programs. You might want to take a look to see if one of them would suit you better:
CommandCam
RobotEyez
Ted
Hi,
I know it’s been many years since you wrote this code. But I have hope maybe you still have the EXE file and I can download it? He can be very helpful in my project for my studies. Thank you very much for your help!