直接上代码吧!

在窗体上调用的类:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms; using System.Net;
using System.Net.Sockets;
using System.Threading; namespace 实时视频传输系统
{
public partial class MainForm : Form
{
public MainForm()
{
InitializeComponent();
}
/// <summary>
/// 声明Camera类
/// </summary>
Camera ca = null;
//创建一个Thread实例
private Thread thread1;
//创建一个UdpClient实例
private UdpClient udpReceive;
private UdpClient udpSend;
private byte[] bytes;
//private DialogResult result;
private void btnPlay_Click(object sender, EventArgs e)
{
btnPlay.Enabled = false;
btnStop.Enabled = true; ca = new Camera(pictureBox1.Handle, pictureBox1.Width, pictureBox1.Height);
try
{
ca.StartWebCam();
}
catch (Exception)
{
MessageBox.Show("未能初始化摄像头!", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
btnPlay.Enabled = true;
btnStop.Enabled = false;
ca = null;
}
} private void btnStop_Click(object sender, EventArgs e)
{
try
{
ca.CloseWebcam(); btnPlay.Enabled = true;
btnStop.Enabled = false;
}
catch (Exception)
{
MessageBox.Show("摄像头关闭失败!", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
btnPlay.Enabled = true;
btnStop.Enabled = false;
ca = null;
}
} private void btnClose_Click(object sender, EventArgs e)
{
try
{
ca.CloseWebcam(); btnPlay.Enabled = true;
btnStop.Enabled = false;
}
catch (Exception)
{
MessageBox.Show("摄像头关闭失败!", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
btnPlay.Enabled = true;
btnStop.Enabled = false;
ca = null;
} //关闭程序
this.Close();
Application.Exit();
} private IPEndPoint ipLocalPoint;
private EndPoint RemotePoint;
private Socket mySocket;
private bool RunningFlag = false;
private void btnGetIP_Click(object sender, EventArgs e)
{
//string GetIP;
//IPAddress[] AddressList = Dns.GetHostEntry(Dns.GetHostEntry()).AddressList;
//if (AddressList.Length < 1)
//{
// return "";
//}
//return AddressList[0].ToString();
//this.tbGetIP.Text = Convert.ToInt32(AddressList);
}
//IP与端口号有效验证
private int getValidPort(string port)
{
int lport;
//测试端口号是否有效
try
{
//是否为空
if (port == "")
{
throw new ArgumentException("端口号无效,不能启动UDP");
}
lport = System.Convert.ToInt32(port);
}
catch(Exception e)
{
Console.WriteLine("无效的端口号"+ e.ToString());
this.tbGetPort.AppendText("无效的端口号"+ e.ToString()+"\n");
return -;
}
return lport;
}
private IPAddress getValidIP(string ip)
{
IPAddress lip = null;
//测试IP是否有效
try
{
//是否为空
if (!IPAddress.TryParse(ip, out lip))
{
throw new ArgumentException("IP无效,不能启动UDP");
}
}
catch(Exception e)
{
Console.WriteLine("无效的IP:"+ e.ToString());
this.tbGetIP.AppendText("无效的IP:"+ e.ToString() +"\n");
return null;
}
return lip;
} private void MainForm_Load(object sender, EventArgs e)
{
thread1 = new Thread(new ThreadStart());
thread1.Start();
} private void btnReceive_Click(object sender, EventArgs e)
{
//在本机指定的端口接收
udpReceive = new UdpClient();
//将套接字加入组播组
udpReceive.JoinMulticastGroup(IPAddress.Parse("224.100.0.10"), );
//接收从远程主机发送过来的信息
IPEndPoint iep = new IPEndPoint(IPAddress.Any, );
while (true)
{
//ref表示引用类型的 IPPoint实例接收消息
try
{
bytes = udpReceive.Receive(ref iep);
}
catch
{
DialogResult result = MessageBox.Show("发送失败!");
}
string str = Encoding.UTF8.GetString(bytes, , bytes.Length);
string message = "来自" + iep.ToString() + "的消息";
//显示消息 并以message为消息的标题
DialogResult res = MessageBox.Show(str, message);
}
} private void btnSend_Click_1(object sender, EventArgs e)
{
//初始化UdpClient
udpSend = new UdpClient();
//实际使用时应将127.0.0.1改为服务器的远程IP
IPAddress remoteIPAddress = IPAddress.Parse("127.0.0.1");
IPEndPoint remoteIPEndPoint = new IPEndPoint(remoteIPAddress, );
//将发送内容转换为字节数组
byte[] bytes = System.Text.Encoding.UTF8.GetBytes();
//设置重传次数
int retry = ;
while (true)
{
try
{
udpSend.Send(bytes, bytes.Length, remoteIPEndPoint);
break;
}
catch
{
if (retry < )
{
retry++; continue;
}
else
{
DialogResult result = MessageBox.Show("发送失败!");
break;
}
}
}
} }
}

视频封装类:

using System;
using System.Collections.Generic;
using System.Text; namespace Camera.avicap
{
/// <summary>
/// Camera 的摘要说明。
/// </summary>
public class Camera
{
private IntPtr lwndC;
private IntPtr mControlPtr;
private int mWidth;
private int mHeight; // 构造函数
public Camera(IntPtr handle, int width, int height)
{
mControlPtr = handle;
mWidth = width;
mHeight = height;
} // 帧回调的委托
public delegate void RecievedFrameEventHandler(byte[] data);
public event RecievedFrameEventHandler RecievedFrame;
private AviCapture.FrameEventHandler mFrameEventHandler; // 关闭摄像头
public void CloseWebcam()
{
this.capDriverDisconnect(this.lwndC);
} // 开启摄像头
public void StartWebCam()
{
byte[] lpszName = new byte[];
byte[] lpszVer = new byte[]; AviCapture.capGetDriverDescriptionA(, lpszName, , lpszVer, );
this.lwndC = AviCapture.capCreateCaptureWindowA(lpszName, AviCapture.WS_VISIBLE + AviCapture.WS_CHILD, , , mWidth, mHeight, mControlPtr, ); if (this.capDriverConnect(this.lwndC, ))
{
this.capPreviewRate(this.lwndC, );
this.capPreview(this.lwndC, true);
AviCapture.BITMAPINFO bitmapinfo = new AviCapture.BITMAPINFO();
bitmapinfo.bmiHeader.biSize = AviCapture.SizeOf(bitmapinfo.bmiHeader);
bitmapinfo.bmiHeader.biWidth = this.mWidth;
bitmapinfo.bmiHeader.biHeight = this.mHeight;
bitmapinfo.bmiHeader.biPlanes = ;
bitmapinfo.bmiHeader.biBitCount = ;
this.capSetVideoFormat(this.lwndC, ref bitmapinfo, AviCapture.SizeOf(bitmapinfo));
this.mFrameEventHandler = new AviCapture.FrameEventHandler(FrameCallBack);
this.capSetCallbackOnFrame(this.lwndC, this.mFrameEventHandler);
AviCapture.SetWindowPos(this.lwndC, , , , mWidth, mHeight, );
}
}
// 以下为私有函数
private bool capDriverConnect(IntPtr lwnd, short i)
{
return AviCapture.SendMessage(lwnd, AviCapture.WM_CAP_DRIVER_CONNECT, i, );
} private bool capDriverDisconnect(IntPtr lwnd)
{
return AviCapture.SendMessage(lwnd, AviCapture.WM_CAP_DRIVER_DISCONNECT, , );
} private bool capPreview(IntPtr lwnd, bool f)
{
return AviCapture.SendMessage(lwnd, AviCapture.WM_CAP_SET_PREVIEW, f, );
} private bool capPreviewRate(IntPtr lwnd, short wMS)
{
return AviCapture.SendMessage(lwnd, AviCapture.WM_CAP_SET_PREVIEWRATE, wMS, );
} private bool capSetCallbackOnFrame(IntPtr lwnd, AviCapture.FrameEventHandler lpProc)
{
return AviCapture.SendMessage(lwnd, AviCapture.WM_CAP_SET_CALLBACK_FRAME, , lpProc);
} private bool capSetVideoFormat(IntPtr hCapWnd, ref AviCapture.BITMAPINFO BmpFormat, int CapFormatSize)
{
return AviCapture.SendMessage(hCapWnd, AviCapture.WM_CAP_SET_VIDEOFORMAT, CapFormatSize, ref BmpFormat);
} private void FrameCallBack(IntPtr lwnd, IntPtr lpVHdr)
{
AviCapture.VIDEOHDR videoHeader = new AviCapture.VIDEOHDR();
byte[] VideoData;
videoHeader = (AviCapture.VIDEOHDR)AviCapture.GetStructure(lpVHdr, videoHeader);
VideoData = new byte[videoHeader.dwBytesUsed];
AviCapture.Copy(videoHeader.lpData, VideoData);
if (this.RecievedFrame != null)
this.RecievedFrame(VideoData);
}
}
}

win32的avicap32.dll封装类

using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.Text; namespace Camera.avicap
{
/// <summary>
/// AviCapture 的摘要说明。
/// </summary>
public class AviCapture
{
//通过调用acicap32.dll进行读取摄像头数据
[DllImport("avicap32.dll")]
public static extern IntPtr capCreateCaptureWindowA(byte[] lpszWindowName, int dwStyle, int x, int y, int nWidth, int nHeight, IntPtr hWndParent, int nID);
[DllImport("avicap32.dll")]
public static extern bool capGetDriverDescriptionA(short wDriver, byte[] lpszName, int cbName, byte[] lpszVer, int cbVer);
[DllImport("User32.dll")]
public static extern bool SendMessage(IntPtr hWnd, int wMsg, bool wParam, int lParam);
[DllImport("User32.dll")]
public static extern bool SendMessage(IntPtr hWnd, int wMsg, short wParam, int lParam);
[DllImport("User32.dll")]
public static extern bool SendMessage(IntPtr hWnd, int wMsg, short wParam, FrameEventHandler lParam);
[DllImport("User32.dll")]
public static extern bool SendMessage(IntPtr hWnd, int wMsg, int wParam, ref BITMAPINFO lParam);
[DllImport("User32.dll")]
public static extern int SetWindowPos(IntPtr hWnd, int hWndInsertAfter, int x, int y, int cx, int cy, int wFlags);
[DllImport("avicap32.dll")]
public static extern int capGetVideoFormat(IntPtr hWnd, IntPtr psVideoFormat, int wSize); //部分常量
public const int WM_USER = 0x400;
public const int WS_CHILD = 0x40000000;
public const int WS_VISIBLE = 0x10000000;
public const int SWP_NOMOVE = 0x2;
public const int SWP_NOZORDER = 0x4;
public const int WM_CAP_DRIVER_CONNECT = WM_USER + ;
public const int WM_CAP_DRIVER_DISCONNECT = WM_USER + ;
public const int WM_CAP_SET_CALLBACK_FRAME = WM_USER + ;
public const int WM_CAP_SET_PREVIEW = WM_USER + ;
public const int WM_CAP_SET_PREVIEWRATE = WM_USER + ;
public const int WM_CAP_SET_VIDEOFORMAT = WM_USER + ; // 结构
[StructLayout(LayoutKind.Sequential)]
//VideoHdr
public struct VIDEOHDR
{
[MarshalAs(UnmanagedType.I4)]
public int lpData;
[MarshalAs(UnmanagedType.I4)]
public int dwBufferLength;
[MarshalAs(UnmanagedType.I4)]
public int dwBytesUsed;
[MarshalAs(UnmanagedType.I4)]
public int dwTimeCaptured;
[MarshalAs(UnmanagedType.I4)]
public int dwUser;
[MarshalAs(UnmanagedType.I4)]
public int dwFlags;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = )]
public int[] dwReserved;
} [StructLayout(LayoutKind.Sequential)]
//BitmapInfoHeader
public struct BITMAPINFOHEADER
{
[MarshalAs(UnmanagedType.I4)]
public Int32 biSize;
[MarshalAs(UnmanagedType.I4)]
public Int32 biWidth;
[MarshalAs(UnmanagedType.I4)]
public Int32 biHeight;
[MarshalAs(UnmanagedType.I2)]
public short biPlanes;
[MarshalAs(UnmanagedType.I2)]
public short biBitCount;
[MarshalAs(UnmanagedType.I4)]
public Int32 biCompression;
[MarshalAs(UnmanagedType.I4)]
public Int32 biSizeImage;
[MarshalAs(UnmanagedType.I4)]
public Int32 biXPelsPerMeter;
[MarshalAs(UnmanagedType.I4)]
public Int32 biYPelsPerMeter;
[MarshalAs(UnmanagedType.I4)]
public Int32 biClrUsed;
[MarshalAs(UnmanagedType.I4)]
public Int32 biClrImportant;
} [StructLayout(LayoutKind.Sequential)]
//BitmapInfo
public struct BITMAPINFO
{
[MarshalAs(UnmanagedType.Struct, SizeConst = )]
public BITMAPINFOHEADER bmiHeader;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = )]
public Int32[] bmiColors;
} public delegate void FrameEventHandler(IntPtr lwnd, IntPtr lpVHdr); // 公共函数
public static object GetStructure(IntPtr ptr, ValueType structure)
{
return Marshal.PtrToStructure(ptr, structure.GetType());
} public static object GetStructure(int ptr, ValueType structure)
{
return GetStructure(new IntPtr(ptr), structure);
} public static void Copy(IntPtr ptr, byte[] data)
{
Marshal.Copy(ptr, data, , data.Length);
} public static void Copy(int ptr, byte[] data)
{
Copy(new IntPtr(ptr), data);
} public static int SizeOf(object structure)
{
return Marshal.SizeOf(structure);
}
}
}

出处:https://bbs.csdn.net/topics/390039653

参考:

https://blog.csdn.net/NCTU_to_prove_safety/article/details/53584905

https://www.cnblogs.com/JUSTSOSOBLOG/p/4612801.html

https://blog.csdn.net/laolei1986/article/details/5730245

https://blog.csdn.net/waeceo/article/details/50222781

======================================================================================================

我使用AVICAP32.DLL来捕获图像,捕完并保存到文件后,当我关闭它后.那个黑块的窗体一直在那里,如果让它消失呢?

哈哈哈,我自己搞定了,由于那个窗体是使用API调出来的,它只是位置和大小与PANEL一样而已,因此要想控制它还是要使用API消息机制.利用它的句柄来操作它.方法如下:

public const int WM_CLOSE = 0x10;//关闭窗口句柄
//关闭摄像头
 if hWndC <> 0 then
  begin
   SendMessage(hWndC, WM_CAP_DRIVER_DISCONNECT, 0, 0);
   SendMessage(hWndC, WM_CLOSE, 0, 0);
   hWndC := 0;
  end;OK,完事了.

======================================================================================================

前面的代码有一个事件的处理是缺失的,就是Camera类的RecievedFrame事件;怎么把接收到的byte[] VideoData数组转成图片呢?

看看下面的文章,或许对你有所启发。

得到摄像头一帧数据的字节数组之后转成图片的处理

最新文章

  1. Rafy 框架 - 幽灵插件(假删除)
  2. iOS中push视图的时候,屏幕中间会出现一条灰色的粗线的解决方案
  3. backup3
  4. 复制mueclipse项目到eclipse
  5. Android开发之Menu和actionBar
  6. HDU 2852 KiKi&#39;s K-Number(离线+树状数组)
  7. C中的setjmp与longjmp
  8. vimium快捷键列表
  9. pd的django To do list 教程------(1)说明与展示
  10. iOS设计模式解析(六)代理模式
  11. Mac下Cordova开发环境搭建
  12. Highcharts选项配置详细说明文档
  13. 使用swagger实现web api在线接口文档
  14. 使用REST风格架构您需要知道的一些事
  15. CodeForces - 796C Bank Hacking
  16. go Test的实现 以及 压力测试
  17. Date类、SimpleDateFormat类
  18. JavaScript中B继承A的方法
  19. git flow 使用步骤
  20. java poi处理excel多sheet并实现排序

热门文章

  1. spring boot使用AOP统一处理web请求
  2. React 的高级用法(Children、Component、createElement、cloneElement)
  3. Codeforces Round #249 (Div. 2) C. Cardiogram
  4. Redis初识01 (简介、安装、使用)
  5. 大数据之路【第十四篇】:数据挖掘--推荐算法(Mahout工具)
  6. .NET/C# 如何获取当前进程的 CPU 和内存占用?如何获取全局 CPU 和内存占用?
  7. oracle基础知识语法大全
  8. 使用NPOI进行Excel操作
  9. SpringbBoot之JPA批量更新
  10. docker swarm yaml