Click here to Skip to main content
15,889,872 members
Please Sign up or sign in to vote.
1.00/5 (1 vote)
See more:
C#
using System;
using System.Collections;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.IO;
using System.Text;
using System.Windows.Forms;
using System.Runtime.InteropServices;
using System.Xml;
using TSTExplorerDesktop;
namespace TSTExplorer
{
    //<summary>
    //This class takes a snapshot from any or all attached webcams
    //</summary>

    
    class CapturePicture
    {
        XmlDocument lpicxmldoc = new XmlDocument();
        ArrayList Devices = new ArrayList();
        
            const short WM_CAP = 0x400;
            const int WM_CAP_DRIVER_CONNECT = WM_CAP + 10;
            const int WM_CAP_DRIVER_DISCONNECT = WM_CAP + 11;
            const int WM_CAP_EDIT_COPY = WM_CAP + 30;
            const int WS_CHILD = 0x40000000;
            const int WS_VISIBLE = 0x10000000;
            
            int Height = 480;
            int Width = 640;

       

        //This function enables send the specified message to a window or windows
        [DllImport("user32", EntryPoint = "SendMessageA")]
        protected static extern int SendMessage(int hwnd, int wMsg, int wParam, [MarshalAs(UnmanagedType.AsAny)] object lParam);
        //This function enables create a  window child with so that you can display it in a picturebox for example
        [DllImport("avicap32.dll")]
        protected static extern int capCreateCaptureWindowA([MarshalAs(UnmanagedType.VBByRefStr)] ref string lpszWindowName,int dwStyle, int x, int y, int nWidth, int nHeight, int hWndParent, int nID);


        //This function enables enumerate the web cam devices
        [DllImport("avicap32.dll")]
        protected static extern bool capGetDriverDescriptionA(short wDriverIndex, [MarshalAs(UnmanagedType.VBByRefStr)]ref String lpszName,int cbName, [MarshalAs(UnmanagedType.VBByRefStr)] ref String lpszVer, int cbVer);
        

        
        //public string OutputPath = Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory);
        //public string FilenamePrefix = "snapshot";

        public void  New()
            {
	            mLoadDeviceList();
            }
        public void mLoadDeviceList()
        {
            
            string lsName = String.Empty.PadRight(100);
            string lsVers = String.Empty.PadRight(100);
            bool lbReturn = false;
            short x = 0;
          
            // Load name of all avialable devices into the lstDevices .
            do
            {
                //   Get Driver name and version
                lbReturn = capGetDriverDescriptionA(x , ref lsName, 100, ref lsVers, 100);
                // If there was a device add device name to the list
                if (lbReturn)
                   
                    Devices.Add(lsName.Trim());
                
                x += 1;
            } while (!(lbReturn == false));
        }
        public void TakePicture()
        {
            int i;

            for (i = 0; i <= this.Devices.Count - 1; i++)
            {
                string lsFilename = Login.logdir + "\\images\\" + Login.luserid + "_" + BuildLog.curtime + ".png";  //Syste.io.Path.Combine(OutputPath, this.FilenamePrefix + i + ".jpg");
                TakePicture(i, lsFilename);
            }


        }
        public void TakePicture(int iDevice)
        {
            string filename = Login.logdir + "\\images\\" + Login.luserid  + "_" + BuildLog.curtime + ".png" ;
            //fnbuildFolderStructure("images");
            //<small></small>buildxmlforPicture(System.IO.Path.GetDirectoryName(Login.logdir), filename, Login.luserid + "_" + BuildLog.curtime + ".png");
            mLoadDeviceList();
             this.TakePicture(iDevice, filename);
        }
        public void TakePicture(int iDevice, string filename)
        {
            string tmpiDevice = Convert.ToString(iDevice);
            int lhHwnd = 0;
            int i;
            // Handle to preview window

            // Create a form to play with
            using (System.Windows.Forms.Form loWindow = new System.Windows.Forms.Form())
            {

                // Create capture window
                lhHwnd = capCreateCaptureWindowA(ref tmpiDevice, WS_VISIBLE | WS_CHILD, 0, 0, this.Width, this.Height, loWindow.Handle.ToInt32(), 0);
                
                // Hook up the device
                SendMessage(lhHwnd, WM_CAP_DRIVER_CONNECT, iDevice, 0);
                // Allow the webcam apeture to let enough light in
                for (i = 1; i <= 10; i++)
                {
                    Application.DoEvents();
                }

                // Copy image to clipboard
                SendMessage(lhHwnd, WM_CAP_EDIT_COPY, 0, 0);

                // Get image from clipboard and convert it to a bitmap
                IDataObject loData = Clipboard.GetDataObject();
                if (loData.GetDataPresent(typeof(System.Drawing.Bitmap)))
                {
                    using (Image loBitmap = (Image)loData.GetData(typeof(System.Drawing.Bitmap)))
                    {
                        loBitmap.Save(filename,System.Drawing.Imaging.ImageFormat.Png );
                    }
                }

                //SendMessage(lhHwnd, WM_CAP_DRIVER_DISCONNECT, iDevice, 0);

            }
        }


        


        

    }
    
}


The above code is working only for 1 shot of picture. But I want to capture picture every 1 minute. I am unable to work it out. Can you help me. I tried setting time interval using timers but it failed to capture the pictures. On debugging i found that when it is called for second time there is nothing in
IDataObject loData = Clipboard.GetDataObject();
cipboard and hence it does not save any image. Please can any 1 help me even with alternative solution?
Posted
Comments
Sergey Alexandrovich Kryukov 18-Sep-14 13:11pm    
Do the shots in an infinite loop, in a separate thread with Thread.Sleep of required time inside the loop. Record real time using either System.DateTime.Now or (relative to some moment of time, with great accuracy) using System.Diagnostics.Stopwatch.
—SA

1 solution

Please see my comment to the question. Assuming TakePicture works correctly, call it (starting with all set-up calls to the device) in a separate thread. And then take pictures in a loop, using System.Threading.Thread.Sleep calls of required duration in each loop.

If you need to record the exact time of each picture, use either System.DateTime.Now or (relative to some moment of time, with great accuracy) using System.Diagnostics.Stopwatch:
http://msdn.microsoft.com/en-us/library/system.datetime.now%28v=vs.110%29.aspx[^],
http://msdn.microsoft.com/en-us/library/system.diagnostics.stopwatch%28v=vs.110%29.aspx[^].

If you need to present something in the UI (progress, some or all images), you need to use UI thread synchronization mechanism. You cannot call anything related to UI from non-UI thread. Instead, you need to use the method Invoke or BeginInvoke of System.Windows.Threading.Dispatcher (for both Forms or WPF) or System.Windows.Forms.Control (Forms only).

You will find detailed explanation of how it works and code samples in my past answers:
Control.Invoke() vs. Control.BeginInvoke()[^],
Problem with Treeview Scanner And MD5[^].

See also more references on threading:
How to get a keydown event to operate on a different thread in vb.net[^],
Control events not firing after enable disable + multithreading[^].

For creation and using a thread, please read about the concept of a thread wrapper and my advice for thread reuse and thread control:
Making Code Thread Safe[^],
Running exactly one job/thread/process in webservice that will never get terminated (asp.net)[^].

—SA
 
Share this answer
 

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



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900