如何在一段时间间隔内使用此程序拍照? [英] How to use this program to take picture in some time interval?
本文介绍了如何在一段时间间隔内使用此程序拍照?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!
问题描述
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);
}
}
}
}
以上代码仅适用于1张照片。但我想每1分钟捕捉一次图片。我无法解决这个问题。你能帮助我吗。我尝试使用计时器设置时间间隔,但无法捕获图片。在调试时,我发现当第二次调用时,
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中没有任何内容,因此它不会保存任何图像。即使有替代解决方案,也可以帮助我吗?
cipboard and hence it does not save any image. Please can any 1 help me even with alternative solution?
推荐答案
请参阅我对该问题的评论。假设TakePicture
正常工作,请在单独的线程中调用它(从对设备的所有设置调用开始)。然后在循环中拍照,使用System.Threading.Thread.Sleep
在每个循环中调用所需的持续时间。
如果您需要记录每张图片的确切时间,请使用System.DateTime.Now
或(相对于某个时刻,非常准确)使用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 [ ^ ]。
如果您需要在UI中显示某些内容(进度,部分或全部图像),则需要使用UI线程同步机制。您不能从非UI线程调用与UI相关的任何内容。相反,您需要使用Invoke
或
System.Windows.Threading的方法
。 Dispatcher
(对于Forms或WPF)或System.Windows.Forms.Control
(仅限表单)。
您将在我过去的答案中找到有关其工作原理和代码示例的详细说明:
Control.Invoke()与Control.BeginInvoke() [ ^ ],
使用Treeview扫描仪和MD5的问题 [ ^ ]。
另请参阅有关线程的更多参考资料:
如何让keydown事件在不同的操作上运行vb.net中的线程 [ ^ ],
在启用禁用+多线程后控制事件未触发 [ ^ ]。
对于创建和使用线程,请阅读线程包装器的概念以及我对线程重用和线程控制的建议:
使代码线程安全 [ ^ ],
在webservice中运行一个永远不会被终止的作业/线程/进程(asp.net) [< a href =http://www.codeproject.com/Answers/182898/Running-exactly-one-job-thread-process-in-webservi.aspx\"target =_ blanktitle =New Window> ^ ]。
-SA
Please see my comment to the question. AssumingTakePicture
works correctly, call it (starting with all set-up calls to the device) in a separate thread. And then take pictures in a loop, usingSystem.Threading.Thread.Sleep
calls of required duration in each loop.
If you need to record the exact time of each picture, use eitherSystem.DateTime.Now
or (relative to some moment of time, with great accuracy) usingSystem.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 methodInvoke
orBeginInvoke
ofSystem.Windows.Threading.Dispatcher
(for both Forms or WPF) orSystem.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
这篇关于如何在一段时间间隔内使用此程序拍照?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!
查看全文