Click here to Skip to main content
Rate this: bad
good
Please Sign up or sign in to vote.
See more: C#4.0
i am using the webcam_capture.dll to capture image from a webcam.
i have written this code to run my console application.
 
Program.cs
using System;
using System.IO;
using System.Drawing;
using System.Diagnostics;
using System.Drawing.Imaging;
 
namespace WebcamPictureCapture
{
    class Program
    {
        static void Main(string[] args)
        {
            Webcam camera = new Webcam();
            Image captured_image;
 
            camera.Start();
            captured_image = camera.GetImage();
            camera.Stop();
 
            using (FileStream fs = new FileStream("f:\\newimage.jpg", FileMode.Create))
            {
                captured_image.Save(fs, ImageFormat.Jpeg);
            }
           
        }
 
    }
}
 
And Webcam.cs
using System;
using WebCam_Capture;
using System.Drawing;
 
namespace WebcamPictureCapture
{
    class Webcam
    {
        private WebCamCapture webcam;
        private Image _FrameImage;
 
        public Webcam()
        {
            webcam = new WebCamCapture();
            webcam.FrameNumber = ((ulong)(0ul));
            webcam.TimeToCapture_milliseconds = 30;
            webcam.ImageCaptured += new WebCamCapture.WebCamEventHandler(webcam_ImageCaptured);
        }
 
        void webcam_ImageCaptured(object source, WebcamEventArgs e)
        {
            _FrameImage = e.WebCamImage;
        }
 
        public void Start()
        {
            webcam.TimeToCapture_milliseconds = 30;
            webcam.Start(0);
        }
 
        public void Stop()
        {
            webcam.Stop();
        }
 
        public Image GetImage()
        {
            return (Image)_FrameImage.Clone();
        }
    }
}
somehow my webcam.ImageCaptured event is not firing & hence no image can be captured. WHY????
 
Thanks in advance for all the help
Posted 10-Sep-12 21:34pm
Rate this: bad
good
Please Sign up or sign in to vote.

Solution 1

I do not know the original author for this code, but works hi-fi. It does not need any third party dll..
using System;
using System.Collections;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Windows.Forms;
using System.Runtime.InteropServices;
 
namespace WebCam_Capture
{
 /// <summary>
 /// Summary description for UserControl1.
 /// </summary>
 [System.Drawing.ToolboxBitmap(typeof(WebCamCapture), "CAMERA.ICO")] // toolbox bitmap
 [Designer("Sytem.Windows.Forms.Design.ParentControlDesigner,System.Design", typeof(System.ComponentModel.Design.IDesigner))] // make composite
 public class WebCamCapture : System.Windows.Forms.UserControl
 {
  private System.ComponentModel.IContainer components;
  private System.Windows.Forms.Timer timer1;
 
  // property variables
  private int m_TimeToCapture_milliseconds = 100;
  private int m_Width = 320;
  private int m_Height = 240;
  private int mCapHwnd;
  private ulong m_FrameNumber = 0;
 
  // global variables to make the video capture go faster
  private WebCam_Capture.WebcamEventArgs x = new WebCam_Capture.WebcamEventArgs();
  private IDataObject tempObj;
  private System.Drawing.Image tempImg;
  private bool bStopped = true;
 
  // event delegate
  public delegate void WebCamEventHandler (object source, WebCam_Capture.WebcamEventArgs e);
  // fired when a new image is captured
  public event WebCamEventHandler ImageCaptured;
 
  #region API Declarations
 
  [DllImport("user32", EntryPoint="SendMessage")]
  public static extern int SendMessage(int hWnd, uint Msg, int wParam, int lParam);
 
  [DllImport("avicap32.dll", EntryPoint="capCreateCaptureWindowA")]
  public static extern int capCreateCaptureWindowA(string lpszWindowName, int dwStyle, int X, int Y, int nWidth, int nHeight, int hwndParent, int nID);
 
  [DllImport("user32", EntryPoint="OpenClipboard")]
  public static extern int OpenClipboard(int hWnd);
 
  [DllImport("user32", EntryPoint="EmptyClipboard")]
  public static extern int EmptyClipboard();
 
  [DllImport("user32", EntryPoint="CloseClipboard")]
  public static extern int CloseClipboard();
 
  #endregion
 
  #region API Constants
 
  public const int WM_USER = 1024;
 
  public const int WM_CAP_CONNECT = 1034;
  public const int WM_CAP_DISCONNECT = 1035;
  public const int WM_CAP_GET_FRAME = 1084;
  public const int WM_CAP_COPY = 1054;
 
  public const int WM_CAP_START = WM_USER;
 
  public const int WM_CAP_DLG_VIDEOFORMAT = WM_CAP_START + 41;
  public const int WM_CAP_DLG_VIDEOSOURCE = WM_CAP_START + 42;
  public const int WM_CAP_DLG_VIDEODISPLAY = WM_CAP_START + 43;
  public const int WM_CAP_GET_VIDEOFORMAT = WM_CAP_START + 44;
  public const int WM_CAP_SET_VIDEOFORMAT = WM_CAP_START + 45;
  public const int WM_CAP_DLG_VIDEOCOMPRESSION = WM_CAP_START + 46;
  public const int WM_CAP_SET_PREVIEW = WM_CAP_START + 50;
 
  #endregion
 
  #region NOTES
 
  /*
   * If you want to allow the user to change the display size and
   * color format of the video capture, call:
   * SendMessage (mCapHwnd, WM_CAP_DLG_VIDEOFORMAT, 0, 0);
   * You will need to requery the capture device to get the new settings
  */
 
  #endregion
 

  public WebCamCapture()
  {
   // This call is required by the Windows.Forms Form Designer.
   InitializeComponent();
  }
 
  /// <summary>
  /// Override the class's finalize method, so we can stop
  /// the video capture on exit
  /// </summary>
  ~WebCamCapture()
  {
   this.Stop();
  }
 
  /// <summary>
  /// Clean up any resources being used.
  /// </summary>
  protected override void Dispose( bool disposing )
  {
   if( disposing )
   {
 
    if( components != null )
     components.Dispose();
   }
   base.Dispose( disposing );
  }
 
  #region Component Designer generated code
  /// <summary>
  /// Required method for Designer support - do not modify
  /// the contents of this method with the code editor.
  /// </summary>
  private void InitializeComponent()
  {
   this.components = new System.ComponentModel.Container();
   this.timer1 = new System.Windows.Forms.Timer(this.components);
   //
   // timer1
   //
   this.timer1.Tick += new System.EventHandler(this.timer1_Tick);
   //
   // WebCamCapture
   //
   this.Name = "WebCamCapture";
   this.Size = new System.Drawing.Size(342, 252);
   this.Load += new System.EventHandler(this.WebCamCapture_Load);
 
  }
  #endregion
 
  #region Control Properties
 
  /// <summary>
  /// The time intervale between frame captures
  /// </summary>
  public int TimeToCapture_milliseconds
  {
   get
   { return m_TimeToCapture_milliseconds; }
 
   set
   { m_TimeToCapture_milliseconds = value; }
  }
 
  /// <summary>
  /// The height of the video capture image
  /// </summary>
  public int CaptureHeight
  {
   get
   { return m_Height; }
 
   set
   { m_Height = value; }
  }
 
  /// <summary>
  /// The width of the video capture image
  /// </summary>
  public int CaptureWidth
  {
   get
   { return m_Width; }
 
   set
   { m_Width = value; }
  }
 
  /// <summary>
  /// The sequence number to start at for the frame number. OPTIONAL
  /// </summary>
  public ulong FrameNumber
  {
   get
   { return m_FrameNumber; }
 
   set
   { m_FrameNumber = value; }
  }
 
  #endregion
 
  #region Start and Stop Capture Functions
 
  /// <summary>
  /// Starts the video capture
  /// </summary>
  /// <param name="FrameNumber">the frame number to start at.
  /// Set to 0 to let the control allocate the frame number</param>
  public void Start(ulong FrameNum)
  {
   try
   {
    // for safety, call stop, just in case we are already running
    this.Stop();
 
    // setup a capture window
    mCapHwnd = capCreateCaptureWindowA("WebCap", 0, 0, 0, m_Width, m_Height, this.Handle.ToInt32(), 0);
 
    // connect to the capture device
    Application.DoEvents();
    SendMessage(mCapHwnd, WM_CAP_CONNECT, 0, 0);
    SendMessage(mCapHwnd, WM_CAP_SET_PREVIEW, 0, 0);
 
    // set the frame number
    m_FrameNumber = FrameNum;
 
    // set the timer information
    this.timer1.Interval = m_TimeToCapture_milliseconds;
    bStopped = false;
    this.timer1.Start();
   }
 
   catch (Exception excep)
   {
    MessageBox.Show("An error ocurred while starting the video capture. Check that your webcamera is connected properly and turned on.\r\n\n" + excep.Message);
    this.Stop();
   }
  }
 
  /// <summary>
  /// Stops the video capture
  /// </summary>
  public void Stop()
  {
   try
   {
    // stop the timer
    bStopped = true;
    this.timer1.Stop();
 
    // disconnect from the video source
    Application.DoEvents();
    SendMessage(mCapHwnd, WM_CAP_DISCONNECT, 0, 0);
   }
 
   catch (Exception excep)
   { // don't raise an error here.
   }
 
  }
 
  #endregion
 
  #region Video Capture Code
 
  /// <summary>
  /// Capture the next frame from the video feed
  /// </summary>
  private void timer1_Tick(object sender, System.EventArgs e)
  {
   try
   {
    // pause the timer
    this.timer1.Stop();
 
    // get the next frame;
    SendMessage(mCapHwnd, WM_CAP_GET_FRAME, 0, 0);
 
    // copy the frame to the clipboard
    SendMessage(mCapHwnd, WM_CAP_COPY, 0, 0);
 
    // paste the frame into the event args image
    if (ImageCaptured != null)
    {
     // get from the clipboard
     tempObj = Clipboard.GetDataObject();
     tempImg = (System.Drawing.Bitmap) tempObj.GetData(System.Windows.Forms.DataFormats.Bitmap);
 
     /*
     * For some reason, the API is not resizing the video
     * feed to the width and height provided when the video
     * feed was started, so we must resize the image here
     */
     x.WebCamImage = tempImg.GetThumbnailImage(m_Width, m_Height, null, System.IntPtr.Zero);
 
     // raise the event
     this.ImageCaptured(this, x);
    }
 
    // restart the timer
    Application.DoEvents();
    if (! bStopped)
     this.timer1.Start();
   }
 
   catch (Exception excep)
   {
    MessageBox.Show("An error ocurred while capturing the video image. The video capture will now be terminated.\r\n\n" + excep.Message);
    this.Stop(); // stop the process
   }
  }
 
  #endregion
 
  private void WebCamCapture_Load(object sender, System.EventArgs e)
  {
 
  }
 }
}
  Permalink  
v3
Comments
Member 10749399 at 8-May-14 7:36am
   
..... plz do code step by step
Kuthuparakkal at 15-Jul-14 15:57pm
   
Read from the beginning, its not my code... Having eyes doesn't mean....
Rate this: bad
good
Please Sign up or sign in to vote.

Solution 2

I solved this problem myself too.
I used the Aforge dlls to do it.
Thanks for all the help i received.
 
Program.cs
using System;
using System.IO;
using System.Drawing;
using System.Security;
using System.Threading;
using System.Diagnostics;
using System.Windows.Forms;
using System.Drawing.Imaging;
 
namespace ImageCapture
{
    class Program
    {
        //program entry point
        [STAThread]
        static int Main(string[] args)
        {
            //variable declaration
            Webcam camera = new Webcam(new Size(320,240),30);
            Image captured_image = null;
            int counter = 0;
            String logfilename="";
 
            try
            {
                /* Raise an exception if no command line parameter
                 * has been passed to the program
                */
                if (args.Length != 1)
                {
                    throw new FileNotFoundException();
                }
 
                //remove any extensions from target file name
                int lastdot=-1;
                lastdot=args[0].LastIndexOf(".");
                if (lastdot!=-1 && !args[0].Substring(lastdot).Contains("\\"))
                    args[0] = args[0].Substring(0, lastdot);
 
                //asign the same log file name as the target file name
                logfilename = new String(args[0].ToCharArray());
 
                //Assign proper extensions to both filenames
                if (!args[0].EndsWith(".jpg", true, null))
                    args[0] = args[0] + ".jpg";
 
                if (!logfilename.EndsWith(".log", true, null))
                    logfilename = logfilename + ".log";
 
                string curr_dir = Environment.CurrentDirectory;
 
                //modify filenames to show absolute file paths
                if (!args[0].Contains("\\"))
                    args[0] = curr_dir + "\\" + args[0];
 
                if (!logfilename.Contains("\\"))
                    logfilename = curr_dir + "\\" + logfilename;
 
                //start the camera
                camera.Start();
                //start listening for windows messages
                Application.DoEvents();                         
 
                /* Try capturing the image from the webcam 100 times
                 * with sleeping 10 milliseconds before each try.
                */
                do
                {
                    Thread.Sleep(10);
                    captured_image = camera.currentImage;
                    counter++;
                } while (captured_image == null && counter <= 100);
 
                /* Processing has been finished
                 * so successful or not, "stop" the camera
                */
                camera.Stop();
 
                /* If unsuccessful for all 100 times, raise an exception
                 * or else process the captured image.
                */
                if (captured_image == null)
                {
                    throw new Exception("Device time-out");
                }
                else
                {
                    //write to both target & log files
                    using (FileStream fs = new FileStream(args[0], FileMode.Create))
                    {
                        captured_image.Save(fs, ImageFormat.Jpeg);
                        Console.WriteLine("Image stored at " + args[0]);
                        WriteLog("Image stored at " + args[0], logfilename);
                    }
                }
            }
            catch (FileNotFoundException)
            {
                Console.WriteLine("Error code 1 : Please specify two valid file-paths");
                return 1;
            }
            catch (ArgumentException)
            {
                Console.WriteLine("Error code 2 : Invalid path");
                WriteLog("Error code 2 : Invalid path", logfilename);
                return 2;
            }
            catch (NotSupportedException)
            {
                Console.WriteLine("Error code 3 : Path refers to a non-file device");
                WriteLog("Error code 3 : Path refers to a non-file device", logfilename);
                return 3;
            }
            catch (SecurityException)
            {
                Console.WriteLine("Error code 4 : Permission denied");
                WriteLog("Error code 4 : Permission denied", logfilename);
                return 4;
            }
            catch (DirectoryNotFoundException)
            {
                Console.WriteLine("Error code 5 : Directory not found");
                WriteLog("Error code 5 : Directory not found", logfilename);
                return 5;
            }
            catch (PathTooLongException)
            {
                Console.WriteLine("Error code 6 : Path is too long");
                WriteLog("Error code 6 : Path is too long", logfilename);
                return 6;
            }
            catch (Exception ex)
            {
                Console.WriteLine("Error code 7 : " + ex.Message);
                WriteLog("Error code 7 : " + ex.Message, logfilename);
                return 7;
            }
            finally
            {
                Application.Exit();
            }
            return 0;
        }
 
        //method to write the log file
        private static void WriteLog(string message, string logfilepath)
        {
            try
            {
                using (StreamWriter writer = File.AppendText(logfilepath))
                {
                    writer.WriteLine(message);
                }
            }
            catch (FileNotFoundException)
            {
                Console.WriteLine("Error code 1 : Please specify a valid log file-path");
            }
            catch (ArgumentException)
            {
                Console.WriteLine("Error code 2 : Invalid log path");
            }
            catch (NotSupportedException)
            {
                Console.WriteLine("Error code 3 : Log file-path refers to a non-file device");
            }
            catch (SecurityException)
            {
                Console.WriteLine("Error code 4 : Log file-path permission denied");
            }
            catch (DirectoryNotFoundException)
            {
                Console.WriteLine("Error code 5 : Log file-path directory not found");
            }
            catch (PathTooLongException)
            {
                Console.WriteLine("Error code 6 : Log file-path is too long");
            }
            catch (Exception ex)
            {
                Console.WriteLine("Error code 7 : " + ex.Message);
            }
        }
    }
}
 
Webcam.cs
using System;
using System.Drawing;
 
using AForge.Video;
using AForge.Video.DirectShow;
 
namespace ImageCapture
{
    class Webcam
    {
        private FilterInfoCollection videoDevices = null;       //list of all videosources connected to the pc
        private VideoCaptureDevice videoSource = null;          //the selected videosource
        private Size frameSize;
        private int frameRate;
 
        public Bitmap currentImage;                             //parameter accessible to outside world to capture the current image

        public Webcam(Size framesize, int framerate)
        {
            this.frameSize = framesize;
            this.frameRate = framerate;
            this.currentImage = null;
        }
 
        // get the devices names cconnected to the pc
        private FilterInfoCollection getCamList()
        {
            videoDevices = new FilterInfoCollection(FilterCategory.VideoInputDevice);
            return videoDevices;
        }
 
        //start the camera
        public void Start()
        {
            //raise an exception incase no video device is found
            //or else initialise the videosource variable with the harware device
            //and other desired parameters.
            if (getCamList().Count == 0)
                throw new Exception("Video device not found");
            else
            {
                videoSource = new VideoCaptureDevice(videoDevices[0].MonikerString);
                videoSource.NewFrame += new NewFrameEventHandler(video_NewFrame);
                videoSource.DesiredFrameSize = this.frameSize;
                videoSource.DesiredFrameRate = this.frameRate;
                videoSource.Start();
            }
        }
 
        //dummy method required for Image.GetThumbnailImage() method
        private bool imageconvertcallback()
        {
            return false;
        }
 
        //eventhandler if new frame is ready
        private void video_NewFrame(object sender, NewFrameEventArgs eventArgs)
        {
            this.currentImage = (Bitmap)eventArgs.Frame.GetThumbnailImage(frameSize.Width, frameSize.Height, new Image.GetThumbnailImageAbort(imageconvertcallback), IntPtr.Zero);
        }
 
        //close the device safely
        public void Stop()
        {
            if (!(videoSource == null))
                if (videoSource.IsRunning)
                {
                    videoSource.SignalToStop();
                    videoSource = null;
                }
        }
    }
}
  Permalink  
Comments
bborac at 12-Apr-14 9:23am
   
Don't like the looping stuff.
The camera.start()-Method takes on my computer about 2s to be ready, after that time period I could safely take pictures.
 
camera.Start();
//start listening for windows messages
//Application.DoEvents();
Thread.Sleep(2000);
captured_image = camera.currentImage;
bborac at 15-Apr-14 4:24am
   
And by the way, RAM usage increases every second by the app to a threshold of 500MB, after that it gets garbage collected, RAM usage decreases again to 40,000K and increases again...
The problem is the following method:
bborac at 15-Apr-14 4:25am
   
//eventhandler if new frame is ready
private void video_NewFrame(object sender, NewFrameEventArgs eventArgs)
{
this.currentImage = (Bitmap)eventArgs.Frame.GetThumbnailImage(frameSize.Width, frameSize.Height, new Image.GetThumbnailImageAbort(imageconvertcallback), IntPtr.Zero);
}

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



Advertise | Privacy | Mobile
Web04 | 2.8.1411022.1 | Last Updated 15 Apr 2014
Copyright © CodeProject, 1999-2014
All Rights Reserved. Terms of Service
Layout: fixed | fluid

CodeProject, 503-250 Ferrand Drive Toronto Ontario, M3C 3G8 Canada +1 416-849-8900 x 100