Page 1 of 1

Taking a webcam video frame as snapshot using AForge.Video.D

PostPosted: Sun Mar 25, 2018 10:50 pm
by latheesan
I am trying to use the AForge.NET SDK like this via helper library (e.g. MyApp.DLL) in my app like this:

Code: Select all
    namespace MyApp.Lib
    {
        public class WebCam
        {
            public static Dictionary<string, string> DeviceList
            {
                get
                {
                    var deviceList = new Dictionary<string, string>();
   
                    try
                    {
                        FilterInfoCollection videoDevices = new FilterInfoCollection(FilterCategory.VideoInputDevice);
   
                        if (videoDevices.Count > 0)
                        {
                            foreach (FilterInfo videoDevice in videoDevices)
                            {
                                deviceList[videoDevice.MonikerString] = videoDevice.Name;
                            }
                        }
                        else
                        {
                            Logger.WriteLog(LogLevel.Error, "No webcam devices were detected.");
                        }
   
                        videoDevices = null;
                    }
                    catch (Exception exception)
                    {
                        Logger.WriteLog(LogLevel.Fatal, "Failed to load a list of available webcam devices - " + exception.Message, exception);
                    }
   
                    return deviceList;
                }
            }
   
            public static string TakeSnapshot
            {
                get
                {
                    string snapshotPath = "";
                   
                    try
                    {
                        string selectedWebCam = Machine.AppConfig.WebCam;
   
                        if (!string.IsNullOrEmpty(selectedWebCam))
                        {
                            string selectedWebCamDeviceId = DeviceList.Single(s => s.Value == selectedWebCam).Key;
   
                            VideoCaptureDevice videoCaptureSource = new VideoCaptureDevice(selectedWebCamDeviceId);
   
                            using (VideoSourcePlayer videoSourcePlayer = new VideoSourcePlayer())
                            {
                                videoSourcePlayer.VideoSource = videoCaptureSource;
                                videoSourcePlayer.Start();
   
                                if (videoSourcePlayer.IsRunning)
                                {
                                    using (Bitmap snapshotFrame = videoSourcePlayer.GetCurrentVideoFrame())
                                    using (Bitmap snapshotFrameResized = ResizeBitmap(snapshotFrame, Constants.WEBCAM_SNAPSHOT_WIDTH, Constants.WEBCAM_SNAPSHOT_HEIGHT))
                                    {
                                        snapshotPath = FileManager.GetPath(Constants.APP_DATA_DIR, string.Format("{0}.jpg", Machine.Udid));
                                        snapshotFrameResized.Save(snapshotPath, ImageFormat.Jpeg);
                                    }
                                }
   
                                videoSourcePlayer.SignalToStop();
                                videoSourcePlayer.WaitForStop();
                            }
   
                            videoCaptureSource = null;
                        }
                    }
                    catch (Exception exception)
                    {
                        Logger.WriteLog(LogLevel.Fatal, "Failed to take a webcam snapshot - " + exception.Message, exception);
                    }
   
                    return snapshotPath;
                }
            }
   
            private static Bitmap ResizeBitmap(Bitmap originalBitmap, int newWidth, int newHeight)
            {
                // snipped ...
            }
        }
    }


When I try to use my helper library like this (in a console app):

Code: Select all
   string webcamSnapshotPath = WebCam.TakeSnapshot;
   Console.WriteLine("webcamSnapshotPath: {0}", webcamSnapshotPath);


I am getting the following exception:

Object reference not set to an instance of an object.


So, I stepped through the code and noticed that the error is caused by this line:

using (Bitmap snapshotFrame = videoSourcePlayer.GetCurrentVideoFrame())


The videoSourcePlayer.GetCurrentVideoFrame() is returning null - even though the video source player was reporting that it's running.

Any idea what I might be doing wrong here?

Is this not possible to implement this functionality into a helper .dll?

I did a separate WinForm test using most of the code above and it's working correctly - I am able to select a webcam and take a snapshot, resize the image and save it as a .jpg file; it's just not working as implemented above:

https://pastebin.com/vJEB55Xk

Any help on this will be much appreciated.

P.S. I've already stepped through the app and verified that variables like selectedWebCamDeviceId is correct.

Re: Taking a webcam video frame as snapshot using AForge.Vid

PostPosted: Mon Mar 26, 2018 7:04 am
by andrew.kirillov
latheesan wrote:The videoSourcePlayer.GetCurrentVideoFrame() is returning null - even though the video source player was reporting that it's running.

Even though it reports it is running, does not mean much. You need to wait for NewFrame event. If the first video frame did not yet come, then video source player has nothing to provide, but null.