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.

Leave a Reply

Your email address will not be published. Required fields are marked *