winform 通过摄像头将本机的监控视频传送到远端机器显示
程序分为服务器端和客户端,需要引入DirectX.Capture和DShowNET类库,有需要的朋友可以E-Mail: yiai027@163.com ,下面分别从服务器端和客户端解释代码:
欢迎加入我的qq群讨论: 74085440 ,该群专注于winform开发,本程序和blog中的其它程序都会放到群中.
代码已发在群中共享,请有需要的朋友下载
原理是把本机的视频保存为图片格式(这里是jpg格式),然后通过流传到对方机器,对方机器再从流中提取图片信息显示到picturebox中
服务器端:
Code
1 TcpListener tcpListen = null;
2 MemoryStream ms = null;
3
4
5 private void Form1_Load(object sender, EventArgs e)
6 {
7 //start new thread 启动新的线程
8 Thread t = new Thread(new ThreadStart(start));
9 t.Start();
10 }
11
12
13
14 private void start()
15 {
16
17 IPEndPoint ipendPoint = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 8002);
18 tcpListen = new TcpListener(ipendPoint);
19 tcpListen.Start(); //start listen 开始监听
20 Socket s = tcpListen.AcceptSocket();
21
22
23 //accept remote info
24 while (true)
25 {
26
27 Byte[] receiveBytes = new Byte[1000000];
28 Int32 i = s.Receive(receiveBytes);
29 ms = new MemoryStream(receiveBytes);//translate bytes to memorystream
30 ShowPicture(ms); //show image from memorystream
31 System.Drawing.Imaging.ImageFormat.Jpeg); //通过调用委托函数将流中的图片信息显示到界面的picturebox控件中
32
33 Byte[] sendBytes = new Byte[100];
34 Int32 j = s.Send(Encoding.UTF8.GetBytes("FaceBack"));
35 }
36 }
37
38
39
40
41 delegate void ShowPictureDele(MemoryStream ms);
42 private void ShowPicture(MemoryStream ms)
43 {
44 // 判断是否在线程中访问 chinese
45 if (!this.pictureBox1.InvokeRequired)
46 {
47 // 不是的话直接操作控件
48 pictureBox1.Image = Image.FromStream(ms);
49 ms.Close();
50 }
51 else
52 {
53 // 是的话启用delegate访问
54 ShowPictureDele showProgress = new ShowPictureDele(ShowPicture);
55 // 如使用Invoke会等到函数调用结束,而BeginInvoke不会等待直接往后走
56 this.BeginInvoke(showProgress, new object[] { ms });
57 }
58 }
1 TcpListener tcpListen = null;
2 MemoryStream ms = null;
3
4
5 private void Form1_Load(object sender, EventArgs e)
6 {
7 //start new thread 启动新的线程
8 Thread t = new Thread(new ThreadStart(start));
9 t.Start();
10 }
11
12
13
14 private void start()
15 {
16
17 IPEndPoint ipendPoint = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 8002);
18 tcpListen = new TcpListener(ipendPoint);
19 tcpListen.Start(); //start listen 开始监听
20 Socket s = tcpListen.AcceptSocket();
21
22
23 //accept remote info
24 while (true)
25 {
26
27 Byte[] receiveBytes = new Byte[1000000];
28 Int32 i = s.Receive(receiveBytes);
29 ms = new MemoryStream(receiveBytes);//translate bytes to memorystream
30 ShowPicture(ms); //show image from memorystream
31 System.Drawing.Imaging.ImageFormat.Jpeg); //通过调用委托函数将流中的图片信息显示到界面的picturebox控件中
32
33 Byte[] sendBytes = new Byte[100];
34 Int32 j = s.Send(Encoding.UTF8.GetBytes("FaceBack"));
35 }
36 }
37
38
39
40
41 delegate void ShowPictureDele(MemoryStream ms);
42 private void ShowPicture(MemoryStream ms)
43 {
44 // 判断是否在线程中访问 chinese
45 if (!this.pictureBox1.InvokeRequired)
46 {
47 // 不是的话直接操作控件
48 pictureBox1.Image = Image.FromStream(ms);
49 ms.Close();
50 }
51 else
52 {
53 // 是的话启用delegate访问
54 ShowPictureDele showProgress = new ShowPictureDele(ShowPicture);
55 // 如使用Invoke会等到函数调用结束,而BeginInvoke不会等待直接往后走
56 this.BeginInvoke(showProgress, new object[] { ms });
57 }
58 }
客户端:
Code
1 #region 字段和属性
2 Capture capture = null;
3 Filters filters = new Filters();
4 TcpClient tcpClinet = new TcpClient();
5
6 Socket s = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
7 #endregion
8
9
10
11 /// <summary>
12 /// 监控
13 /// </summary>
14 private void btnMonitor_Click(object sender, EventArgs e)
15 {
16 try
17 {
18
19 //实例化Capture
20 capture = new Capture(filters.VideoInputDevices[0], filters.AudioInputDevices[0]);// new capture instance
21
22 if (!capture.Cued)
23 {
24 //必须先设置存储路径,才能调用Cue()函数
25 //set save path
26 capture.Filename = this.txtSavePath.Text.Trim(); //捕获的视频存储到本地硬盘
27
28 capture.Cue();
29 }
30
31 //预览模式 preview on the picturebox1
32 if (capture.PreviewWindow == null)
33 {
34 capture.PreviewWindow = this.pictureBox1;
35 }
36
37 //开始捕获
38 capture.Start(); //start capture
39
40 }
41 catch (Exception ex)
42 {
43 }
44 }
45
46
47
48 /// <summary>
49 /// 停止 stop capture
50 /// </summary>
51 private void btnStop_Click(object sender, EventArgs e)
52 {
53
54 //停止捕获视频
55 if (capture != null)
56 {
57 capture.Stop();
58 capture.PreviewWindow = null;
59 capture.Dispose();
60 }
61 }
62
63
64
65
66 #region 截图,并通过socket将截图的流文件传送到其它机器 screenShot
67 /// <summary>
68 /// 截图
69 /// </summary>
70 private void btnScreenshot_Click(object sender, EventArgs e)
71 {
72 try
73 {
74
75 IPEndPoint remoteIp = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 8002);
76
77 s.Connect(remoteIp);
78
79 if (s.Connected)
80 {
81 if (capture != null)
82 {
83 capture.FrameEvent2 += new Capture.HeFrame(CaptureDone);
84 capture.GrapImg();
85 }
86 }
87 }
88 catch (Exception ex)
89 {
90 }
91 }
92
93 MemoryStream ms = null;
94
95 Byte[] sendBytes=new Byte[1000000];
96 Byte[] receiveBytes = new Byte[100];
97
98 private void CaptureDone(System.Drawing.Bitmap e)
99 {
100 try
101 {
102
103 ms = new MemoryStream();
104
105 this.pictureBox1.Image = e;
106 this.pictureBox1.Image.Save(ms, System.Drawing.Imaging.ImageFormat.Jpeg);
107
108 sendBytes = ms.GetBuffer();
109 Int32 i = s.Send(sendBytes);
110 ms.Close();
111
112 Int32 j = s.Receive(receiveBytes);
113
114 }
115 catch (Exception ex)
116 {
117 }
118 }
119 #endregion
120
1 #region 字段和属性
2 Capture capture = null;
3 Filters filters = new Filters();
4 TcpClient tcpClinet = new TcpClient();
5
6 Socket s = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
7 #endregion
8
9
10
11 /// <summary>
12 /// 监控
13 /// </summary>
14 private void btnMonitor_Click(object sender, EventArgs e)
15 {
16 try
17 {
18
19 //实例化Capture
20 capture = new Capture(filters.VideoInputDevices[0], filters.AudioInputDevices[0]);// new capture instance
21
22 if (!capture.Cued)
23 {
24 //必须先设置存储路径,才能调用Cue()函数
25 //set save path
26 capture.Filename = this.txtSavePath.Text.Trim(); //捕获的视频存储到本地硬盘
27
28 capture.Cue();
29 }
30
31 //预览模式 preview on the picturebox1
32 if (capture.PreviewWindow == null)
33 {
34 capture.PreviewWindow = this.pictureBox1;
35 }
36
37 //开始捕获
38 capture.Start(); //start capture
39
40 }
41 catch (Exception ex)
42 {
43 }
44 }
45
46
47
48 /// <summary>
49 /// 停止 stop capture
50 /// </summary>
51 private void btnStop_Click(object sender, EventArgs e)
52 {
53
54 //停止捕获视频
55 if (capture != null)
56 {
57 capture.Stop();
58 capture.PreviewWindow = null;
59 capture.Dispose();
60 }
61 }
62
63
64
65
66 #region 截图,并通过socket将截图的流文件传送到其它机器 screenShot
67 /// <summary>
68 /// 截图
69 /// </summary>
70 private void btnScreenshot_Click(object sender, EventArgs e)
71 {
72 try
73 {
74
75 IPEndPoint remoteIp = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 8002);
76
77 s.Connect(remoteIp);
78
79 if (s.Connected)
80 {
81 if (capture != null)
82 {
83 capture.FrameEvent2 += new Capture.HeFrame(CaptureDone);
84 capture.GrapImg();
85 }
86 }
87 }
88 catch (Exception ex)
89 {
90 }
91 }
92
93 MemoryStream ms = null;
94
95 Byte[] sendBytes=new Byte[1000000];
96 Byte[] receiveBytes = new Byte[100];
97
98 private void CaptureDone(System.Drawing.Bitmap e)
99 {
100 try
101 {
102
103 ms = new MemoryStream();
104
105 this.pictureBox1.Image = e;
106 this.pictureBox1.Image.Save(ms, System.Drawing.Imaging.ImageFormat.Jpeg);
107
108 sendBytes = ms.GetBuffer();
109 Int32 i = s.Send(sendBytes);
110 ms.Close();
111
112 Int32 j = s.Receive(receiveBytes);
113
114 }
115 catch (Exception ex)
116 {
117 }
118 }
119 #endregion
120
现在有个问题,改程序可以将摄像头捕获到的视频在远端机器上显示,但必须给一个路径将捕获的视频存储到本地硬盘,虽然视频可以压缩,但还是需要占用大量的空间,希望各位能够解决这个问题,不用在本地存储,只要捕获--发送即可