- 作者:老汪软件技巧
- 发表时间:2024-10-13 15:03
- 浏览量:
class="hljs language-ini" lang="ini">using System;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Net.Http;
using System.Windows.Forms;
public class VideoForm : Form
{
private PictureBox pictureBox;
private HttpClient httpClient;
public VideoForm()
{
pictureBox = new PictureBox
{
Dock = DockStyle.Fill,
SizeMode = PictureBoxSizeMode.StretchImage
};
this.Controls.Add(pictureBox);
httpClient = new HttpClient();
Timer timer = new Timer();
timer.Interval = 100; // Adjust the interval as needed
timer.Tick += Timer_Tick;
timer.Start();
}
private async void Timer_Tick(object sender, EventArgs e)
{
try
{
HttpResponseMessage response = await httpClient.GetAsync("http://localhost:5000/video_frame");
response.EnsureSuccessStatusCode();
string jsonResponse = await response.Content.ReadAsStringAsync();
dynamic jsonData = Newtonsoft.Json.JsonConvert.DeserializeObject(jsonResponse);
string base64String = jsonData.image;
byte[] imageBytes = Convert.FromBase64String(base64String);
using (MemoryStream ms = new MemoryStream(imageBytes))
{
Image image = Image.FromStream(ms);
pictureBox.Image = image;
}
}
catch (Exception ex)
{
MessageBox.Show($"Error: {ex.Message}");
}
}
[STAThread]
public static void Main()
{
Application.EnableVisualStyles();
Application.Run(new VideoForm());
}
}
方法二:通过ZeroMQ传输视频数据
ZeroMQ是一种高性能的异步消息库,适用于需要低延迟和高吞吐量的应用。
服务器端(Python)
使用pyzmq库发送视频帧。
import zmq
import cv2
import numpy as np
context = zmq.Context()
socket = context.socket(zmq.PUB)
socket.bind("tcp://*:5555")
cap = cv2.VideoCapture('your_video.mp4')
while True:
ret, frame = cap.read()
if not ret:
break
frame_rgb = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
frame_bytes = frame_rgb.tobytes()
socket.send_string("FRAME", zmq.SNDMORE)
socket.send(frame_bytes, flags=0, copy=False)
客户端(C#)
使用NetMQ库接收视频帧。
using System;
using System.Drawing;
using System.Drawing.Imaging;
using System.Runtime.InteropServices;
using System.Threading.Tasks;
using System.Windows.Forms;
using NetMQ;
using NetMQ.Sockets;
public class VideoForm : Form
{
private PictureBox pictureBox;
private SubscriberSocket subscriber;
public VideoForm()
{
pictureBox = new PictureBox
{
Dock = DockStyle.Fill,
SizeMode = PictureBoxSizeMode.StretchImage
};
this.Controls.Add(pictureBox);
var address = "tcp://localhost:5555";
using (var context = NetMQContext.Create())
{
subscriber = context.CreateSubscriberSocket();
subscriber.Connect(address);
subscriber.Subscribe("FRAME");
Task.Run(() => ReceiveFramesAsync(subscriber));
}
}
private async Task ReceiveFramesAsync(SubscriberSocket subscriber)
{
while (true)
{
var topic = await subscriber.ReceiveFrameStringAsync();
var frameBytes = await subscriber.ReceiveFrameBytesAsync();
if (topic == "FRAME")
{
int width = 640; // Adjust based on your video resolution
int height = 480; // Adjust based on your video resolution
int stride = width * 3;
Bitmap bitmap = new Bitmap(width, height, PixelFormat.Format24bppRgb);
BitmapData bitmapData = bitmap.LockBits(new Rectangle(0, 0, width, height), ImageLockMode.WriteOnly, bitmap.PixelFormat);
Marshal.Copy(frameBytes, 0, bitmapData.Scan0, frameBytes.Length);
bitmap.UnlockBits(bitmapData);
pictureBox.Image = bitmap;
}
}
}
[STAThread]
public static void Main()
{
Application.EnableVisualStyles();
Application.Run(new VideoForm());
}
}
方法三:通过共享内存或文件
如果C#和Python运行在同一台机器上,可以通过共享内存或文件系统进行数据交换。这种方法相对简单,但性能可能不如前两种方法。