跪求C#程序如何能将摄像头的图像导入? 请问如何可以从摄像头获取数据并导入到c#的Form里,从这里:http://download.csdn.net/source/434425 下载了一个,总说要转换,转换后总是不能用,本人使用VS2005,转换后运行的结果总是一片黑,什么也看不到,望哪位专家高手给指点,在线等待您的解释!谢谢! 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 用接口获取并加载摄像头 用timer进行监视 在一个按钮下面用流或反射控制其何时获取图形 API 貌似是这样的 也不是很清除 希望这个对你会有点帮助 试试用bitblt直接截图,这样应该不用转换了 要调用摄像头的驱动程序或它的API接口函数。应该有相应的文档把 。 2楼的意见倒是不错,我先试试……大家还有什么建议么?这个是我看到的代码using System;using System.Collections.Generic;using System.ComponentModel;using System.Drawing;using System.Data;using System.Text;using System.Windows.Forms;using System.Runtime.InteropServices;using System.Drawing.Imaging;namespace CameraDemo{ public partial class Camera : UserControl { private int hHwnd; public string fileName = "*";//照片的文件名 public int width = 240;//照片的尺寸为宽度:240,高度:320,即:240*320 public int height = 320; public bool isOpen = false; /// <summary> /// 必需的设计器变量。 /// </summary> [DllImport("avicap32.dll", CharSet = CharSet.Ansi, SetLastError = true, ExactSpelling = true)] public static extern int capCreateCaptureWindowA([MarshalAs(UnmanagedType.VBByRefStr)] ref string lpszWindowName, int dwStyle, int x, int y, int nWidth, short nHeight, int hWndParent, int nID); [DllImport("user32", CharSet = CharSet.Ansi, SetLastError = true, ExactSpelling = true)] public static extern bool DestroyWindow(int hndw); [DllImport("user32", EntryPoint = "SendMessageA", CharSet = CharSet.Ansi, SetLastError = true, ExactSpelling = true)] public static extern int SendMessage(int hwnd, int wMsg, int wParam, [MarshalAs(UnmanagedType.AsAny)] object lParam); [DllImport("user32", CharSet = CharSet.Ansi, SetLastError = true, ExactSpelling = true)] public static extern int SetWindowPos(int hwnd, int hWndInsertAfter, int x, int y, int cx, int cy, int wFlags); public Camera() { InitializeComponent(); //Clipboard.Clear(); } private void OpenCapture() { int intWidth = this.videoWindow.Width; int intHeight = this.videoWindow.Height; int intDevice = 0; string refDevice = intDevice.ToString(); hHwnd = Camera.capCreateCaptureWindowA(ref refDevice, 1342177280, 0, 0, 640, 480, this.videoWindow.Handle.ToInt32(), 0); if (Camera.SendMessage(hHwnd, 0x40a, intDevice, 0) > 0) { Camera.SendMessage(this.hHwnd, 0x435, -1, 0); Camera.SendMessage(this.hHwnd, 0x434, 0x42, 0); Camera.SendMessage(this.hHwnd, 0x432, -1, 0); Camera.SetWindowPos(this.hHwnd, 1, 0, 0, intWidth, intHeight, 6); isOpen = true; } else { Camera.DestroyWindow(this.hHwnd); } } private void btn_OpenCapture_Click(object sender, EventArgs e)//打开摄像头,显示视频 { this.OpenCapture(); } private void btn_GetCapture_Click(object sender, EventArgs e)//抓取图像 { try { Camera.SendMessage(this.hHwnd, 0x41e, 0, 0); IDataObject obj_camera = Clipboard.GetDataObject(); if (obj_camera.GetDataPresent(typeof(Bitmap))) { Image image_camera = ((Image)obj_camera.GetData(typeof(Bitmap))).GetThumbnailImage(width, height, null, IntPtr.Zero); //设置图片的尺寸为240*320 SaveFileDialog SaveFileDialog_camera = new SaveFileDialog(); SaveFileDialog_camera.FileName = fileName + ".jpg"; SaveFileDialog_camera.Filter = "Image Files(*.JPG)|*.JPG"; if (SaveFileDialog_camera.ShowDialog() == DialogResult.OK) { image_camera.Save(SaveFileDialog_camera.FileName, ImageFormat.Jpeg); } } else { MessageBox.Show("摄像头没有开启,不能抓图,请开启摄像头!", "提示信息", MessageBoxButtons.OK, MessageBoxIcon.Information); } } catch { MessageBox.Show("抓取图像时出现错误!", "错误信息", MessageBoxButtons.OK, MessageBoxIcon.Error); } } private void btn_CloseCapture_Click(object sender, EventArgs e)//关闭摄像头 { Camera.SendMessage(this.hHwnd, 0x40b, 0, 0); Camera.DestroyWindow(this.hHwnd); Clipboard.Clear();//清除剪切板中的内容 isOpen = false; } private void btn_set_Click(object sender, EventArgs e)//对摄像头进行设置 { if (isOpen) Camera.SendMessage(this.hHwnd, 0x42a, 0, 0); else MessageBox.Show("摄像头没有开启,不能设置,请开启摄像头!", "提示信息", MessageBoxButtons.OK, MessageBoxIcon.Information); } private void btn_kinescope_Click(object sender, EventArgs e)//开始录像,录像过程中鼠标成漏斗形,对着图像显示区域单击鼠标左键或右键就结束了录像。 { if (isOpen) { SaveFileDialog SaveFileDialog_Video = new SaveFileDialog(); SaveFileDialog_Video.FileName = fileName + ".avi"; SaveFileDialog_Video.Filter = "Video Files(*.avi)|*.avi"; if (SaveFileDialog_Video.ShowDialog() == DialogResult.OK) { SendMessage(this.hHwnd, 0x414, 0, SaveFileDialog_Video.FileName); SendMessage(this.hHwnd, 0x43e, 0, 0); } } else MessageBox.Show("摄像头没有开启,不能录像,请开启摄像头!", "提示信息", MessageBoxButtons.OK, MessageBoxIcon.Information); } private void btn_stopKinescope_Click(object sender, EventArgs e)//停止录像 { SendMessage(this.hHwnd, 0x444, 0, 0); } }} 以上代码,是我最近找到的一个用vs2005做的自定义摄像头工具,问题还是一样,初始化后窗口videoWindow显示的是一片漆黑,而且抓图功能总是跳到catch语句里,最郁闷的是居然录像可以使用,而且能录到我需要录的图像,各位谁能帮忙看看呢? 傻办法,全屏截屏,再截取你要的部分,呵呵Image myImage = new Bitmap(Screen.PrimaryScreen.Bounds.Width, Screen.PrimaryScreen.Bounds.Height); Graphics g = Graphics.FromImage(myImage); g.CopyFromScreen(new Point(0, 0), new Point(0, 0), new Size(Screen.PrimaryScreen.Bounds.Width, Screen.PrimaryScreen.Bounds.Height)); IntPtr dc1 = g.GetHdc(); g.ReleaseHdc(dc1); g.Dispose(); ShowImage((Bitmap)myImage); // 改成你的处理看看 这个把哪几句改掉呢?还有ShowImage是个方法还是什么?我怎么在帮助文档里找不到呢? 最近我看了一段delphi的片段代码,貌似也是摄像头的,但是我只有片段:Const WM_CAP_START = WM_USER;\\1024 0x400Const WM_CAP_STOP = WM_CAP_START + 68;\\1092 0x444Const WM_CAP_DRIVER_CONNECT = WM_CAP_START + 10;\\1034 0x40AConst WM_CAP_DRIVER_DISCONNECT = WM_CAP_START + 11;\\1035 0x40BConst WM_CAP_SAVEDIB = WM_CAP_START + 25;\\1049 0x419Const WM_CAP_GRAB_FRAME = WM_CAP_START + 60;\\1084 0x43CConst WM_CAP_SEQUENCE = WM_CAP_START + 62;\\1086 0x43EConst WM_CAP_FILE_SET_CAPTURE_FILEA = WM_CAP_START + 20;\\1044 0x414Const WM_CAP_SEQUENCE_NOFILE = WM_CAP_START + 63;\\1087 0x43FConst WM_CAP_SET_OVERLAY = WM_CAP_START + 51;\\1075 0x433Const WM_CAP_SET_PREVIEW = WM_CAP_START + 50;\\1074 0x432Const WM_CAP_SET_CALLBACK_VIDEOSTREAM = WM_CAP_START + 6;\\1030 0x406Const WM_CAP_SET_CALLBACK_ERROR = WM_CAP_START + 2;\\1026 0x402Const WM_CAP_SET_CALLBACK_STATUSA = WM_CAP_START + 3;\\1027 0x403Const WM_CAP_SET_CALLBACK_FRAME = WM_CAP_START + 5;\\1029 0x405Const WM_CAP_SET_SCALE = WM_CAP_START + 53;\\1077 0x435Const WM_CAP_SET_PREVIEWRATE = WM_CAP_START + 52;\\1076 0x434(后面的数字是我根据C#的程序找规律算的十进制数字以及十六进制数字) 程序初始化获取图像:hWndC := capCreateCaptureWindowA('My Own Capture Window', WS_CHILD Or WS_VISIBLE, CSCamFrm.Panel1.Left, CSCamFrm.Panel1.Top, CSCamFrm.Panel1.Width, CSCamFrm.Panel1.Height, CSCamFrm.Handle, 0); If hWndC <> 0 Then Begin SendMessage(hWndC, WM_CAP_SET_CALLBACK_VIDEOSTREAM, 0, 0); SendMessage(hWndC, WM_CAP_SET_CALLBACK_ERROR, 0, 0); SendMessage(hWndC, WM_CAP_SET_CALLBACK_STATUSA, 0, 0); SendMessage(hWndC, WM_CAP_DRIVER_CONNECT, 0, 0); // SendMessage(hWndC, WM_CAP_SET_SCALE, 1, 0); // SendMessage(hWndC, WM_CAP_SET_PREVIEWRATE, 66, 0); SendMessage(hWndC, WM_CAP_SET_OVERLAY, 1, 0); // SendMessage(hWndC, WM_CAP_SET_PREVIEW, 1, 0); End; (打//的是和C#类似的语句)我看着差不多,所以就把程序里的:if (Camera.SendMessage(hHwnd, 0x40a, intDevice, 0) > 0) //if (hHwnd!=0) { Camera.SendMessage(this.hHwnd, 0x435, 1, 0); Camera.SendMessage(this.hHwnd, 0x434, 0x42, 0); Camera.SendMessage(this.hHwnd, 0x432, 1, 0); Camera.SetWindowPos(this.hHwnd, 1, 0, 0, intWidth, intHeight, 6); isOpen = true; } 改成了:if (Camera.SendMessage(hHwnd, 0x40a, intDevice, 0) > 0) { Camera.SendMessage(this.hHwnd, 0x406, 0, 0); Camera.SendMessage(this.hHwnd, 0x402, 0, 0); Camera.SendMessage(this.hHwnd, 0x403, 0, 0); Camera.SendMessage(this.hHwnd, 0x40a, 0, 0); Camera.SendMessage(this.hHwnd, 0x435, 1, 0);// Camera.SendMessage(this.hHwnd, 0x434, 0x42, 0);// Camera.SendMessage(this.hHwnd, 0x433, 1, 0); Camera.SendMessage(this.hHwnd, 0x432, 1, 0);// Camera.SetWindowPos(this.hHwnd, 1, 0, 0, intWidth, intHeight, 6); isOpen = true; }结果:Camera.SendMessage(this.hHwnd, 0x432, 1, 0);//这句出现一个异常:SEHException,外部组件发生异常。我看if的判断条件貌似和第四句发送代码一样,注释了前四句,结果和原来一样,程序可以运行,但是还是Panel控件里面一片漆黑哪位高人能帮我解决下呢?我已经快想疯了…… 最近我几乎找遍了所有C#编制的摄像头程序,但是总是在框里显示一片漆黑,到底哪里有问题?谁能帮我解释啊!!! T_T 我刚做完,用codeproject.com上的你先用AmCap.exe看看能不能看到图像,有时候需要设置一下分辨率、色彩等等,24位还是16位的 他们都推荐用DirectShow,速度很快 DirectShow是什么?我看文档里面没有啊…… http://www.codeproject.com/KB/directx/directxcapture.aspx http://www.codeproject.com/KB/directx/directxcapture.aspx 这个确实很不错,不知道能不能做成dll在其他工程里调用 directshow不知道哪位大侠帮忙解释一下 你用的方法不稳定 的。。换个带驱动 的摄像头绝对 就好了。。这个问题也困扰了我很长时间。。要么就换个方法,用http://www.codeproject.com/KB/directx/directxcapture.aspx,不过没有截图功能,我也研究了好长时间,本人强烈建议http://developer.51cto.com/art/200908/145646.htm,简单,实用。。 我也遇到同样的问题,C#在vs2005中调用摄像头显示一片黑,不能拍照,但能完成录像,头疼死了,还望那位仁义之士帮帮忙! 队列出栈的数据和入栈数据不一样,晕死! jmail收信中文乱码 怎样模拟点击网页的弹出框? remoting 本地一切正常 放到服务器就是回调的时候总是出错误 nextmatch()不能循环了 我建了一个.Net开发的QQ群,欢迎各位同仁踊跃加入! 求解,事件中EventArgs参数传递类是否可以使用out参数? 高手们帮忙给点建议:多对一c/s结构网络通讯程序设计 如何将查询出的数据集保存成xml文件 C++中函数改成C#中涉及文件操作 c#如何输出enter键的ascii码值? 如何在WINFORM界面上添加一条横线?不要用Label
应该有相应的文档把 。
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Text;
using System.Windows.Forms;using System.Runtime.InteropServices;
using System.Drawing.Imaging;namespace CameraDemo
{
public partial class Camera : UserControl
{
private int hHwnd;
public string fileName = "*";//照片的文件名
public int width = 240;//照片的尺寸为宽度:240,高度:320,即:240*320
public int height = 320;
public bool isOpen = false;
/// <summary>
/// 必需的设计器变量。
/// </summary>
[DllImport("avicap32.dll", CharSet = CharSet.Ansi, SetLastError = true, ExactSpelling = true)]
public static extern int capCreateCaptureWindowA([MarshalAs(UnmanagedType.VBByRefStr)] ref string lpszWindowName, int dwStyle, int x, int y, int nWidth, short nHeight, int hWndParent, int nID);
[DllImport("user32", CharSet = CharSet.Ansi, SetLastError = true, ExactSpelling = true)]
public static extern bool DestroyWindow(int hndw);
[DllImport("user32", EntryPoint = "SendMessageA", CharSet = CharSet.Ansi, SetLastError = true, ExactSpelling = true)]
public static extern int SendMessage(int hwnd, int wMsg, int wParam, [MarshalAs(UnmanagedType.AsAny)] object lParam);
[DllImport("user32", CharSet = CharSet.Ansi, SetLastError = true, ExactSpelling = true)]
public static extern int SetWindowPos(int hwnd, int hWndInsertAfter, int x, int y, int cx, int cy, int wFlags); public Camera()
{
InitializeComponent();
//Clipboard.Clear();
}
private void OpenCapture()
{
int intWidth = this.videoWindow.Width;
int intHeight = this.videoWindow.Height;
int intDevice = 0;
string refDevice = intDevice.ToString();
hHwnd = Camera.capCreateCaptureWindowA(ref refDevice, 1342177280, 0, 0, 640, 480, this.videoWindow.Handle.ToInt32(), 0); if (Camera.SendMessage(hHwnd, 0x40a, intDevice, 0) > 0)
{
Camera.SendMessage(this.hHwnd, 0x435, -1, 0);
Camera.SendMessage(this.hHwnd, 0x434, 0x42, 0);
Camera.SendMessage(this.hHwnd, 0x432, -1, 0);
Camera.SetWindowPos(this.hHwnd, 1, 0, 0, intWidth, intHeight, 6);
isOpen = true;
}
else
{
Camera.DestroyWindow(this.hHwnd);
}
} private void btn_OpenCapture_Click(object sender, EventArgs e)//打开摄像头,显示视频
{
this.OpenCapture();
} private void btn_GetCapture_Click(object sender, EventArgs e)//抓取图像
{
try
{
Camera.SendMessage(this.hHwnd, 0x41e, 0, 0);
IDataObject obj_camera = Clipboard.GetDataObject();
if (obj_camera.GetDataPresent(typeof(Bitmap)))
{
Image image_camera = ((Image)obj_camera.GetData(typeof(Bitmap))).GetThumbnailImage(width, height, null, IntPtr.Zero);
//设置图片的尺寸为240*320 SaveFileDialog SaveFileDialog_camera = new SaveFileDialog();
SaveFileDialog_camera.FileName = fileName + ".jpg";
SaveFileDialog_camera.Filter = "Image Files(*.JPG)|*.JPG";
if (SaveFileDialog_camera.ShowDialog() == DialogResult.OK)
{
image_camera.Save(SaveFileDialog_camera.FileName, ImageFormat.Jpeg);
}
}
else
{
MessageBox.Show("摄像头没有开启,不能抓图,请开启摄像头!", "提示信息", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
}
catch
{
MessageBox.Show("抓取图像时出现错误!", "错误信息", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
} private void btn_CloseCapture_Click(object sender, EventArgs e)//关闭摄像头
{
Camera.SendMessage(this.hHwnd, 0x40b, 0, 0);
Camera.DestroyWindow(this.hHwnd); Clipboard.Clear();//清除剪切板中的内容
isOpen = false;
}
private void btn_set_Click(object sender, EventArgs e)//对摄像头进行设置
{
if (isOpen)
Camera.SendMessage(this.hHwnd, 0x42a, 0, 0);
else
MessageBox.Show("摄像头没有开启,不能设置,请开启摄像头!", "提示信息", MessageBoxButtons.OK, MessageBoxIcon.Information);
} private void btn_kinescope_Click(object sender, EventArgs e)//开始录像,录像过程中鼠标成漏斗形,对着图像显示区域单击鼠标左键或右键就结束了录像。
{
if (isOpen)
{
SaveFileDialog SaveFileDialog_Video = new SaveFileDialog();
SaveFileDialog_Video.FileName = fileName + ".avi";
SaveFileDialog_Video.Filter = "Video Files(*.avi)|*.avi";
if (SaveFileDialog_Video.ShowDialog() == DialogResult.OK)
{
SendMessage(this.hHwnd, 0x414, 0, SaveFileDialog_Video.FileName);
SendMessage(this.hHwnd, 0x43e, 0, 0);
}
}
else
MessageBox.Show("摄像头没有开启,不能录像,请开启摄像头!", "提示信息", MessageBoxButtons.OK, MessageBoxIcon.Information);
} private void btn_stopKinescope_Click(object sender, EventArgs e)//停止录像
{
SendMessage(this.hHwnd, 0x444, 0, 0);
}
}
}
Image myImage = new Bitmap(Screen.PrimaryScreen.Bounds.Width, Screen.PrimaryScreen.Bounds.Height);
Graphics g = Graphics.FromImage(myImage);
g.CopyFromScreen(new Point(0, 0), new Point(0, 0), new Size(Screen.PrimaryScreen.Bounds.Width, Screen.PrimaryScreen.Bounds.Height));
IntPtr dc1 = g.GetHdc();
g.ReleaseHdc(dc1);
g.Dispose();
ShowImage((Bitmap)myImage); // 改成你的处理看看
Const WM_CAP_START = WM_USER;\\1024 0x400
Const WM_CAP_STOP = WM_CAP_START + 68;\\1092 0x444
Const WM_CAP_DRIVER_CONNECT = WM_CAP_START + 10;\\1034 0x40A
Const WM_CAP_DRIVER_DISCONNECT = WM_CAP_START + 11;\\1035 0x40B
Const WM_CAP_SAVEDIB = WM_CAP_START + 25;\\1049 0x419
Const WM_CAP_GRAB_FRAME = WM_CAP_START + 60;\\1084 0x43C
Const WM_CAP_SEQUENCE = WM_CAP_START + 62;\\1086 0x43E
Const WM_CAP_FILE_SET_CAPTURE_FILEA = WM_CAP_START + 20;\\1044 0x414
Const WM_CAP_SEQUENCE_NOFILE = WM_CAP_START + 63;\\1087 0x43F
Const WM_CAP_SET_OVERLAY = WM_CAP_START + 51;\\1075 0x433
Const WM_CAP_SET_PREVIEW = WM_CAP_START + 50;\\1074 0x432
Const WM_CAP_SET_CALLBACK_VIDEOSTREAM = WM_CAP_START + 6;\\1030 0x406
Const WM_CAP_SET_CALLBACK_ERROR = WM_CAP_START + 2;\\1026 0x402
Const WM_CAP_SET_CALLBACK_STATUSA = WM_CAP_START + 3;\\1027 0x403
Const WM_CAP_SET_CALLBACK_FRAME = WM_CAP_START + 5;\\1029 0x405
Const WM_CAP_SET_SCALE = WM_CAP_START + 53;\\1077 0x435
Const WM_CAP_SET_PREVIEWRATE = WM_CAP_START + 52;\\1076 0x434
(后面的数字是我根据C#的程序找规律算的十进制数字以及十六进制数字)
程序初始化获取图像:
hWndC := capCreateCaptureWindowA('My Own Capture Window', WS_CHILD Or WS_VISIBLE, CSCamFrm.Panel1.Left,
CSCamFrm.Panel1.Top,
CSCamFrm.Panel1.Width, CSCamFrm.Panel1.Height, CSCamFrm.Handle, 0);
If hWndC <> 0 Then
Begin
SendMessage(hWndC, WM_CAP_SET_CALLBACK_VIDEOSTREAM, 0, 0);
SendMessage(hWndC, WM_CAP_SET_CALLBACK_ERROR, 0, 0);
SendMessage(hWndC, WM_CAP_SET_CALLBACK_STATUSA, 0, 0);
SendMessage(hWndC, WM_CAP_DRIVER_CONNECT, 0, 0);
// SendMessage(hWndC, WM_CAP_SET_SCALE, 1, 0);
// SendMessage(hWndC, WM_CAP_SET_PREVIEWRATE, 66, 0);
SendMessage(hWndC, WM_CAP_SET_OVERLAY, 1, 0);
// SendMessage(hWndC, WM_CAP_SET_PREVIEW, 1, 0);
End;
(打//的是和C#类似的语句)
我看着差不多,所以就把程序里的:
if (Camera.SendMessage(hHwnd, 0x40a, intDevice, 0) > 0)
//if (hHwnd!=0)
{
Camera.SendMessage(this.hHwnd, 0x435, 1, 0);
Camera.SendMessage(this.hHwnd, 0x434, 0x42, 0);
Camera.SendMessage(this.hHwnd, 0x432, 1, 0);
Camera.SetWindowPos(this.hHwnd, 1, 0, 0, intWidth, intHeight, 6);
isOpen = true;
}
改成了:
if (Camera.SendMessage(hHwnd, 0x40a, intDevice, 0) > 0)
{
Camera.SendMessage(this.hHwnd, 0x406, 0, 0);
Camera.SendMessage(this.hHwnd, 0x402, 0, 0);
Camera.SendMessage(this.hHwnd, 0x403, 0, 0);
Camera.SendMessage(this.hHwnd, 0x40a, 0, 0);
Camera.SendMessage(this.hHwnd, 0x435, 1, 0);//
Camera.SendMessage(this.hHwnd, 0x434, 0x42, 0);//
Camera.SendMessage(this.hHwnd, 0x433, 1, 0);
Camera.SendMessage(this.hHwnd, 0x432, 1, 0);//
Camera.SetWindowPos(this.hHwnd, 1, 0, 0, intWidth, intHeight, 6);
isOpen = true;
}
结果:Camera.SendMessage(this.hHwnd, 0x432, 1, 0);//这句出现一个异常:SEHException,外部组件发生异常。
我看if的判断条件貌似和第四句发送代码一样,注释了前四句,结果和原来一样,程序可以运行,但是还是Panel控件里面一片漆黑
哪位高人能帮我解决下呢?我已经快想疯了……
这个确实很不错,不知道能不能做成dll在其他工程里调用