Capturing Web Cam Pictures with .net
So I recently was working on a project where we needed to be able to have a web cam on a laptop take pictures, and then send those images against a web api endpoint.
Basically the use-cases behind this are plenty, but this was around work done to support using Microsoft Cognitive services. The project itself being a slimmed down version of the intelligent kiosk from Microsoft.
So I have to be honest, I expected this problem to be a lot harder than it actually is. There is a great library that made this work called AForge.Video, that I was able to install from nuget, and from there this is the code required:
static void Main(string[] args) { // enumerate video devices var videoDevices = new FilterInfoCollection( FilterCategory.VideoInputDevice); // create video source VideoCaptureDevice videoSource = new VideoCaptureDevice( videoDevices[0].MonikerString); // set NewFrame event handler videoSource.NewFrame += new NewFrameEventHandler(video_NewFrame); videoSource.ProvideSnapshots = true; // start the video source videoSource.Start(); //videoSource.SignalToStop(); Console.ReadLine(); }
The above code is just identifying the video / photo capture devices available on this machine, and leveraging the first. And then connecting an event to handle new frame capture.
From there, once I turn on “videoSource.Start();” the application starts executing the NewFrameEventHandler to process it.
private static void video_NewFrame(object sender, NewFrameEventArgs eventArgs) { // get new frame Bitmap bitmap = eventArgs.Frame; var fileName = @"C:\temp\camera\File_Frame.jpg"; //bitmap.Save(string.Format(fileName)); EncoderParameters encoderParameters = new EncoderParameters(1); encoderParameters.Param[0] = new EncoderParameter(System.Drawing.Imaging.Encoder.Quality, 100L); bitmap.Save(fileName, GetEncoder(ImageFormat.Jpeg), encoderParameters); var bytes = bitmap.ToByteArray(ImageFormat.Bmp); Thread.Sleep(1000); } public static ImageCodecInfo GetEncoder(ImageFormat format) { ImageCodecInfo[] codecs = ImageCodecInfo.GetImageDecoders(); foreach (ImageCodecInfo codec in codecs) { if (codec.FormatID == format.Guid) { return codec; } } return null; }
Now the event handler above will take the code, and extract the bitmp, convert it to a Jpg and save the file. But additionally I’ve added the logic at the end to convert it to a byte array. This would allow you to push this up to an HTTP endpoint for processing by any services you need. Pretty simple for 74 line of code.