使用不带DirectShow的网络摄像头. [英] Using a Webcam without DirectShow.
本文介绍了使用不带DirectShow的网络摄像头.的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!
问题描述
您好,我想知道是否有一种方法可以使集成的网络摄像头在不使用外部DLL(例如DirectShow等)的情况下工作.我在网上找到了一些代码,但是某些设备ID尚未设置或它需要外部引用.以下使用System 32 API调用,但是设备ID保持空白,不确定如何设置!
class WebCamera:IDisposable
{
#region常量
/// < 摘要 >
/// 常量用于重载非托管代码功能
/// 每个常量代表一个状态
/// < /summary >
私有 const 短 WM_CAP = 0x400;
私有 const int WM_CAP_DRIVER_CONNECT = 0x40a;
私有 const int WM_CAP_DRIVER_DISCONNECT = 0x40b;
私有 const int WM_CAP_EDIT_COPY = 0x41e;
私有 const int WM_CAP_SET_PREVIEW = 0x432;
私有 const int WM_CAP_SET_OVERLAY = 0x433;
私有 const int WM_CAP_SET_PREVIEWRATE = 0x434;
私有 const int WM_CAP_SET_SCALE = 0x435;
私有 const int WS_CHILD = 0x40000000;
私有 const int WS_VISIBLE = 0x10000000;
私有 const short SWP_NOMOVE = 0x2;
私有 短 SWP_NOZORDER = 0x4;
私有 短 HWND_BOTTOM = 1 ;
#endregion
#region DLL和属性
/// < 摘要 >
/// DllImport允许您在系统上导入dll,以使您的代码与之最小化
/// 此功能可枚举WebCam设备
/// < /summary >
[DllImport(" )]]
受保护的 静态 外部 short wDriverIndex,
[MarshalAs(UnmanagedType.VBByRefStr)] 引用 字符串 IpszName,
int cbName,[MarshalAs(UnmanagedType.VBByRefStr)] ref 字符串 IpszVer, int cbVer);
/// < >
/// DllImport允许您在系统上导入dll,以使您的代码与之最小化
/// 创建一个窗口子级,以便您可以在PictureBox中显示它
/// < /summary >
[DllImport(" )]]
受保护的 静态 外部 int capCreateCaptureWindowA([MarshalAs(UnmanagedType.VBByRefStr)] 字符串 lpszWindowName,
int dwStyle, int x, int y , int nWidth, int nHeight, int hWndParent, int nID);
/// < >
/// DllImport允许您在系统上导入dll,以使您的代码与之最小化
/// 此功能可对子窗口的大小,位置和Z顺序进行设置更改
/// < /summary >
/// < 参数 名称="hwnd" < >
/// < 参数 名称="hWndInsertAfter" < >
/// < 参数 名称="x" < >
/// < 参数 名称="y" < >
/// < 参数 名称="cx" < >
/// < 参数 名称="cy" < >
/// < 参数 名称="wFlags" < >
/// < 返回 > < >
[DllImport(" )]
受保护的 静态 外部 int hwnd, int x, int y, int cx, int cy, int wFlags);
/// < >
/// DllImport允许您在系统上导入dll,以使您的代码与之最小化
/// 此功能可将指定的消息发送到一个或多个窗口
/// < /summary >
/// < 参数 名称="hwnd" < >
/// < 参数 名称="wMsg" < >
/// < 参数 名称="wParam" < >
/// < 参数 名称="lParam" < >
/// < 返回 > < >
[DllImport(" ,EntryPoint = " )]
受保护的 静态 外部 int hwnd,对象 lParam);
/// < >
/// DllImport允许您在系统上导入dll,以使您的代码与之最小化
/// 此功能可以销毁窗口子级
/// < /summary >
/// < 参数 名称="hwnd" < >
/// < 返回 > < >
[DllImport(" )]
受保护的 静态 外部 int hwnd);
// 常规设备ID
int DeviceID = 0 ;
// 处理要预览窗口的值
int hHwnd = 0 ;
// 设备列表
ArrayList ListOfDevices = 新 ArrayList();
// 在PictureBox中显示流
公共 PictureBox容器{ get ; 设置; }
#endregion
#region加载方法
// 连接到设备.
/// < >
/// 此函数用于加载设备列表
/// < /summary >
公共 void Load()
{
字符串名称= 字符串 .Empty.PadRight( 100 );
字符串版本= 字符串 .Empty.PadRight( 100 );
布尔 EndOfDeviceList = false ;
短索引= 0 ;
// 将所有可用设备加载并命名为ListOfDevices
做
{
// 获取驱动程序名称和版本
EndOfDeviceList = capGetDriverDescriptionA(index, ref 名称, 100 , ref 版本, 100 );
//
如果(EndOfDeviceList)ListOfDevices.Add(Name.Trim());
索引+ = 1 ;
}
while (!(EndOfDeviceList == false ));
}
#endregion
#region打开连接
公共 void OpenConnection()
{
加载();
字符串 DeviceIndex = Convert.ToString(DeviceID);
// 设置容器(图片框)以处理设备
IntPtr oHandle = Container.Handle;
{
MessageBox.Show(" );
}
// 在图片框中打开预览"窗口.
// 使用capCreateCaptureWindowA创建一个子窗口,以便可以在图片框中显示它.
hHwnd = capCreateCaptureWindowA( ref DeviceIndex,WS_VISIBLE | WS_CHILD, 0 , 0 , 640 , 480 ,oHandle.ToInt32(),// 连接到设备
如果(SendMessage(hHwnd,WM_CAP_DRIVER_CONNECT,DeviceID, 0 )!== // 设置预览比例
SendMessage(hHwnd,WM_CAP_SET_SCALE,-1, 0 );
// 设置预览速率(以毫秒为单位)
SendMessage(hHwnd,WM_CAP_SET_PREVIEWRATE, 66 , 0 );
// 开始预览相机中的图像
SendMessage(hHwnd,WM_CAP_SET_PREVIEW,-1, 0 );
// 调整窗口大小以适合PictureBox
SetWindowPos(hHwnd,HWND_BOTTOM, 0 , 0 ,Container.Height,Container.Width,SWP_NOMOVE | SWP_NOZORDER) ;
}
其他
{
// 由于连接错误而关闭设备
DestroyWindow(hHwnd);
}
}
#endregion
#region关闭连接
公共 void CloseConnection()
{
SendMessage(hHwnd,WM_CAP_DRIVER_DISCONNECT,DeviceID, 0 );
// 关闭窗口
DestroyWindow(hHwnd);
}
#endregion
#region保存图片
/// < 摘要 >
/// 允许您将图像以Bmp类型保存到本地计算机
/// < /summary >
公共 void SaveImage()
{
IDataObject数据;
图片oImage;
SaveFileDialog saveImage = 新 SaveFileDialog();
saveImage.Filter = " ;
// 将图像复制到剪贴板
SendMessage(hHwnd,WM_CAP_EDIT_COPY, 0 , 0 );
// 从剪贴板获取图像并将其转换为位图
数据= Clipboard.GetDataObject();
如果(data.GetDataPresent( typeof (System.Drawing.Bitmap)))
{
oImage =(Image)data.GetData( typeof (System.Drawing.Bitmap));
Container.Image = oImage;
CloseConnection();
如果(saveImage.ShowDialog()== DialogResult.OK)
{
oImage.Save(saveImage.FileName,System.Drawing.Imaging.ImageFormat.Bmp);
}
}
}
#endregion
#region处置方法
/// < 摘要 >
/// 关闭与设备的连接并转储所有剩余的内存使用量
/// < /summary >
公共 void Dispose()
{
CloseConnection();
}
#endregion
}
解决方案
是否有您不想使用DirectShow的特殊原因?
>
Hi, I wanted to know if there is a way of getting my integrated webcam to work without using an external DLL such as directshow etc... I have found some code online, but some the device id is not getting set or it requires external references. The following uses a System 32 API call but device ID remains blank, not to sure how to set it!
class WebCamera : IDisposable
{
#region Constants
/// <summary>
/// Constants are used to overload unmanaged code functions
/// Each Constant represents a state
/// </summary>
private const short WM_CAP = 0x400;
private const int WM_CAP_DRIVER_CONNECT = 0x40a;
private const int WM_CAP_DRIVER_DISCONNECT = 0x40b;
private const int WM_CAP_EDIT_COPY = 0x41e;
private const int WM_CAP_SET_PREVIEW = 0x432;
private const int WM_CAP_SET_OVERLAY = 0x433;
private const int WM_CAP_SET_PREVIEWRATE = 0x434;
private const int WM_CAP_SET_SCALE = 0x435;
private const int WS_CHILD = 0x40000000;
private const int WS_VISIBLE = 0x10000000;
private const short SWP_NOMOVE = 0x2;
private short SWP_NOZORDER = 0x4;
private short HWND_BOTTOM = 1;
#endregion
#region DLLs and properties
/// <summary>
/// DllImport allows you to import dlls on the system for your code to cominicate with
/// This function enables enumerate of WebCam devices
/// </summary>
[DllImport("avicap32.dll")]
protected static extern bool capGetDriverDescriptionA(short wDriverIndex,
[MarshalAs(UnmanagedType.VBByRefStr)] ref String IpszName,
int cbName, [MarshalAs(UnmanagedType.VBByRefStr)] ref String IpszVer, int cbVer);
/// <summary>
/// DllImport allows you to import dlls on the system for your code to cominicate with
/// Creates a window child, so that you can display it in a PictureBox
/// </summary>
[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);
/// <summary>
/// DllImport allows you to import dlls on the system for your code to cominicate with
/// This function enables set changes to the size, position, and Z order of a child window
/// </summary>
/// <param name="hwnd"></param>
/// <param name="hWndInsertAfter"></param>
/// <param name="x"></param>
/// <param name="y"></param>
/// <param name="cx"></param>
/// <param name="cy"></param>
/// <param name="wFlags"></param>
/// <returns></returns>
[DllImport("user32")]
protected static extern int SetWindowPos(int hwnd, int hWndInsertAfter, int x, int y, int cx, int cy, int wFlags);
/// <summary>
/// DllImport allows you to import dlls on the system for your code to cominicate with
/// This function enables send the specified message to a window or windows
/// </summary>
/// <param name="hwnd"></param>
/// <param name="wMsg"></param>
/// <param name="wParam"></param>
/// <param name="lParam"></param>
/// <returns></returns>
[DllImport("user32", EntryPoint = "SendMessageA")]
protected static extern int SendMessage(int hwnd, int wMsg, int wParam, [MarshalAs(UnmanagedType.AsAny)] object lParam);
/// <summary>
/// DllImport allows you to import dlls on the system for your code to cominicate with
/// This function enable destroy the window child
/// </summary>
/// <param name="hwnd"></param>
/// <returns></returns>
[DllImport("user32")]
protected static extern bool DestroyWindow(int hwnd);
// Normal device ID
int DeviceID = 0;
// Handle Value to preview window
int hHwnd = 0;
// The list of devices
ArrayList ListOfDevices = new ArrayList();
//Display stream in PictureBox
public PictureBox Container { get; set; }
#endregion
#region Load Method
// Connects to device.
/// <summary>
/// This function is used to load the list of devices
/// </summary>
public void Load()
{
string Name = String.Empty.PadRight(100);
string Version = String.Empty.PadRight(100);
bool EndOfDeviceList = false;
short index = 0;
//Load and name all of available devices into ListOfDevices
do
{
//Get Driver Name and Version
EndOfDeviceList = capGetDriverDescriptionA(index, ref Name, 100, ref Version, 100);
//
if (EndOfDeviceList) ListOfDevices.Add(Name.Trim());
index += 1;
}
while (!(EndOfDeviceList == false));
}
#endregion
#region Open Connection
public void OpenConnection()
{
Load();
string DeviceIndex = Convert.ToString(DeviceID);
// Setting the Container(PictureBox) to handle the Device
IntPtr oHandle = Container.Handle;
{
MessageBox.Show("Set the container property");
}
// Open Preview window in picturebox .
// Create a child window with capCreateCaptureWindowA so you can display it in a picturebox.
hHwnd = capCreateCaptureWindowA(ref DeviceIndex, WS_VISIBLE | WS_CHILD, 0, 0, 640, 480, oHandle.ToInt32(), 0);
// Connect to the device
if (SendMessage(hHwnd, WM_CAP_DRIVER_CONNECT, DeviceID, 0) != 0)
{
// Set the preview scale
SendMessage(hHwnd, WM_CAP_SET_SCALE, -1, 0);
// Set the preview rate in terms of milliseconds
SendMessage(hHwnd, WM_CAP_SET_PREVIEWRATE, 66, 0);
// Start previewing the image from the camera
SendMessage(hHwnd, WM_CAP_SET_PREVIEW, -1, 0);
//Resize window to fit the PictureBox
SetWindowPos(hHwnd, HWND_BOTTOM, 0, 0, Container.Height, Container.Width, SWP_NOMOVE | SWP_NOZORDER);
}
else
{
// Close device due to connection error
DestroyWindow(hHwnd);
}
}
#endregion
#region Close Connection
public void CloseConnection()
{
SendMessage(hHwnd, WM_CAP_DRIVER_DISCONNECT, DeviceID, 0);
// Close Window
DestroyWindow(hHwnd);
}
#endregion
#region Save Image
/// <summary>
/// Allows you to save image to local machine as type Bmp
/// </summary>
public void SaveImage()
{
IDataObject data;
Image oImage;
SaveFileDialog saveImage = new SaveFileDialog();
saveImage.Filter = "(*.bmp)|*.bmp";
// Copy Image to clipboard
SendMessage(hHwnd, WM_CAP_EDIT_COPY, 0, 0);
// Get Image from clipboard and convert it to a bitmap
data = Clipboard.GetDataObject();
if (data.GetDataPresent(typeof(System.Drawing.Bitmap)))
{
oImage = (Image)data.GetData(typeof(System.Drawing.Bitmap));
Container.Image = oImage;
CloseConnection();
if (saveImage.ShowDialog() == DialogResult.OK)
{
oImage.Save(saveImage.FileName, System.Drawing.Imaging.ImageFormat.Bmp);
}
}
}
#endregion
#region Dispose Method
/// <summary>
/// Closes the connection to device and dumps all remaining memory usage
/// </summary>
public void Dispose()
{
CloseConnection();
}
#endregion
}
解决方案
Is there a particular reason that you do not want to use directshow?
这篇关于使用不带DirectShow的网络摄像头.的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!
查看全文