直接上代码吧!

在窗体上调用的类:

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数组转成图片呢?

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

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

利用avicap32.dll实现的实时视频传输的更多相关文章

  1. FileUpload 上传文件,并实现c#使用Renci.SshNet.dll实现SFTP文件传输

    fileupload上传文件和jquery的uplodify控件使用方法类似,对服务器控件不是很熟悉,记录一下. 主要是记录新接触的sftp文件上传.服务器环境下使用freesshd搭建好环境后,wi ...

  2. Git学习:利用Git和TortoiseGit把代码传输到网络服务器

    版本控制这块,一直用SVN.感觉挺好用,比VSS要好用些.不过,近期在网上,又谈到时下很流行的Git.就想看看Git到底是何方神圣.趁着五一在家无事,就静下心来,简单研究一下. 当下,网络上提供的基于 ...

  3. C# 利用BarcodeLib.dll生成条形码(一维,zxing,QrCodeNet/dll二维码)

    原文:http://blog.csdn.net/kongwei521/article/details/17588825 首先效果: 一.下载BarcodeLib.dll 下载地址 :http://do ...

  4. C# 利用BarcodeLib.dll生成条形码

    首先效果: 1:首先下载BarcodeLib.dll 下载地址 http://pan.baidu.com/share/link?shareid=2590968386&uk=2148890391 ...

  5. C#.net 摄像头驱动程序,用avicap32.dll

    装了摄像头后一般会有 avicap32.dll文件,没有一样可以用这些代码. 不需要在解决方案里面引用这个.dll文件. 下面有二种写法的例子: 例一: using System;using Syst ...

  6. winform利用itextsharp.dll实现图片文件转换PDF格式文件

    1.利用itextsharp.dll实现单个图片文件转换为PDF格式文件, 可以使用以下类: void ConvertJPG2PDF(string jpgfile, string pdf) { var ...

  7. 视频运行库AVICAP32.DLL说明收藏

    视频运行库AVICAP32.DLL说明收藏2008-09-28 09:04 // ----------------------------------------------------------- ...

  8. 利用破解dll来获取到一个软件的注册码

    ---恢复内容开始--- 首先做这个事是纯属于个人研究而已,请勿以侵犯他人劳动成果. 今天看到了一个关于IL语句的文章,于是就学学,然后实践实践下.废话不多说了. 1.安装好某一个需要注册才可以的使用 ...

  9. 利用URLRewriter.dll 实现ASP.NET实现伪静态

    大家一定经常在网络上看到很多网站的地址后缀都是用XX.HTML或者XX.ASPX等类似静态文件的标示来操作的吧,那么大家有怀疑过他真的是一个一个的静态生成的文件么,静态文件的生成的优缺有好有坏,对于访 ...

随机推荐

  1. 远程控制分析之VBS编码转换

    简介 分析这种VBS简单chr()函数编码的脚本技巧.只需要把vbs的execute()函数换成信息输出到控制台(dos窗口)函数就可以了. WSH.Echo "print your mes ...

  2. 解决SQL语句在Dapper执行超时比Query慢的问题

    在语句结尾加上 Add OPTION (RECOMPILE) to the end https://stackoverflow.com/questions/10933366/sp-executesql ...

  3. (CSDN迁移)JAVA多线程实现-继承Thread

    继承Thread方法: extends Thread 重写覆盖run()方法: @Override public void run() 通过start()方法启动线程. threadDemo01.st ...

  4. cf 595 补题

    1.B2   Books Exchange (hard version) 题意:有n(1~n)个孩子看书,定义一个数组,记录了每个孩子看完

  5. js中Boolean类型和Number类型的一些常见方法

    Boolean类型 Boolean类型重写了valueOf() 方法, 返回基本布尔类型值true或false,重写了toString() 方法,返回基本字符串"true" 和 & ...

  6. FastReport For Delphi7 通用安装方法

    安装前请册除原有的FR控件. 1. "Tools|Environmet options..."中的"Library"标签面下"Library path ...

  7. 进程池和线程池、协程、TCP单线程实现并发

    一.进程池和线程池 当被操作对象数目不大时,我们可以手动创建几个进程和线程,十几个几十个还好,但是如果有上百个上千个.手动操作麻烦而且电脑硬件跟不上,可以会崩溃,此时进程池.线程池的功效就能发挥了.我 ...

  8. JAVA如何实现中式排名和美式排名

    根据公司需求,需要编写中式和美式排名算法,根据具体业务编写的,代码如下,看不懂留言,欢迎探讨,求高手指教更高效稳定的方法.private static int[] datas = {9,9,10,10 ...

  9. JS实现简单的图片透明度循环变化(渐变)

    找了好多,都是由100到0就结束了,到头来自己魔改,以下就是源码. div中加入img,js添加函数,完事(调用),取名后面加个1是为了避免冲突 <!DOCTYPE HTML> <h ...

  10. [洛谷P4385][COCI2009]Dvapravca(咕咕咕)

    题目大意:很早以前做的题 题解: 卡点: C++ Code: #pragma GCC optimize("Ofast") #pragma GCC optimize("un ...