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.