Files
ArmDogControl/DogAndArmControl/VideoCaltulate.cs

334 lines
14 KiB
C#
Raw Normal View History

2025-09-26 10:31:23 +08:00
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace DogAndArmControl
{
public class VideoCaltulate
{
private MemoryStream imageBuffer = new MemoryStream(); // 图像数据缓冲区
private byte[] videoBuffer = new byte[1400]; // 视频数据缓冲区
private int videoWidth;
private int videoHeight;
// 原有的单独视频流接收方法(保留兼容性)
public async Task ReceiveVideoFramesAsync(CancellationToken cancellationToken, NetworkStream videoStream, PictureBox VideoBox, bool flag)
{
try
{
while (!cancellationToken.IsCancellationRequested)
{
try
{
// 接收4字节的图像大小信息
int sizeBufferSize = 4;
byte[] sizeBuffer = new byte[sizeBufferSize];
int totalRead = 0;
while (totalRead < sizeBufferSize && !cancellationToken.IsCancellationRequested)
{
int read = await videoStream.ReadAsync(sizeBuffer, totalRead, sizeBufferSize - totalRead, cancellationToken);
if (read == 0) break;
totalRead += read;
}
if (totalRead != sizeBufferSize || cancellationToken.IsCancellationRequested)
{
throw new IOException("未接收到完整的图像大小信息");
}
int imageSize = BitConverter.ToInt32(sizeBuffer, 0);
if (imageSize <= 0 || imageSize > 20 * 1024 * 1024)
{
Debug.WriteLine($"Invalid image size: {imageSize} bytes. Skipping frame.");
continue;
}
// 接收图像数据
imageBuffer.SetLength(0); // 清空缓冲区
int bytesRead = 0;
while (bytesRead < imageSize && !cancellationToken.IsCancellationRequested)
{
int chunkSize = Math.Min(videoBuffer.Length, imageSize - bytesRead);
int read = await videoStream.ReadAsync(videoBuffer, 0, chunkSize, cancellationToken);
if (read == 0) break;
imageBuffer.Write(videoBuffer, 0, read);
bytesRead += read;
}
if (bytesRead != imageSize || cancellationToken.IsCancellationRequested)
{
throw new IOException($"未接收到完整的图像数据,预期: {imageSize}, 实际: {bytesRead}");
}
// 在UI线程上异步更新图像
await Task.Run(() => ProcessImageData(VideoBox, flag));
}
catch (Exception ex)
{
break;
}
}
}
catch (Exception) { }
}
// 新增接收合并视频流并分割显示到两个PictureBox的方法
public async Task ReceiveMergedVideoFramesAsync(CancellationToken cancellationToken, NetworkStream videoStream, PictureBox dogVideoBox, PictureBox armVideoBox)
{
try
{
while (!cancellationToken.IsCancellationRequested)
{
try
{
// 接收4字节的图像大小信息
int sizeBufferSize = 4;
byte[] sizeBuffer = new byte[sizeBufferSize];
int totalRead = 0;
while (totalRead < sizeBufferSize && !cancellationToken.IsCancellationRequested)
{
int read = await videoStream.ReadAsync(sizeBuffer, totalRead, sizeBufferSize - totalRead, cancellationToken);
if (read == 0) break;
totalRead += read;
}
int imageSize = BitConverter.ToInt32(sizeBuffer, 0);
if (imageSize <= 0 || imageSize > 20 * 1024 * 1024)
{
Debug.WriteLine($"Invalid image size: {imageSize} bytes. Skipping frame.");
continue;
}
// 接收图像数据
imageBuffer.SetLength(0); // 清空缓冲区
int bytesRead = 0;
while (bytesRead < imageSize && !cancellationToken.IsCancellationRequested)
{
int chunkSize = Math.Min(videoBuffer.Length, imageSize - bytesRead);
int read = await videoStream.ReadAsync(videoBuffer, 0, chunkSize, cancellationToken);
if (read == 0) break;
imageBuffer.Write(videoBuffer, 0, read);
bytesRead += read;
}
if (bytesRead != imageSize || cancellationToken.IsCancellationRequested)
{
throw new IOException($"未接收到完整的图像数据,预期: {imageSize}, 实际: {bytesRead}");
}
// 处理合并后的图像数据并分割显示
2025-10-13 16:34:23 +08:00
await Task.Run(() => ProcessMergedImageData(dogVideoBox, armVideoBox));
//await Task.Run(() => ProcessImageData(armVideoBox));
2025-09-26 10:31:23 +08:00
}
catch (Exception ex)
{
Debug.WriteLine($"Error receiving merged video frame: {ex.Message}");
break;
}
}
}
catch (Exception ex)
{
Debug.WriteLine($"Error in ReceiveMergedVideoFramesAsync: {ex.Message}");
}
}
// 处理合并后的图像数据并分割显示到两个PictureBox
private void ProcessMergedImageData(PictureBox dogVideoBox, PictureBox armVideoBox)
{
try
{
imageBuffer.Position = 0;
using (var mergedImage = Image.FromStream(imageBuffer))
{
// 获取合并图像的尺寸
int mergedWidth = mergedImage.Width;
int mergedHeight = mergedImage.Height;
// 计算分割点(假设是横向拼接,左右各占一半)
int halfWidth = mergedWidth / 2;
// 创建两个分割后的图像
Bitmap dogImage = new Bitmap(halfWidth, mergedHeight);
Bitmap armImage = new Bitmap(halfWidth, mergedHeight);
using (Graphics dogGraphics = Graphics.FromImage(dogImage))
using (Graphics armGraphics = Graphics.FromImage(armImage))
{
// 分割左半部分给机械狗视频
Rectangle dogSourceRect = new Rectangle(0, 0, halfWidth, mergedHeight);
Rectangle dogDestRect = new Rectangle(0, 0, halfWidth, mergedHeight);
dogGraphics.DrawImage(mergedImage, dogDestRect, dogSourceRect, GraphicsUnit.Pixel);
// 分割右半部分给机械臂视频
Rectangle armSourceRect = new Rectangle(halfWidth, 0, halfWidth, mergedHeight);
Rectangle armDestRect = new Rectangle(0, 0, halfWidth, mergedHeight);
armGraphics.DrawImage(mergedImage, armDestRect, armSourceRect, GraphicsUnit.Pixel);
}
// 在UI线程上更新两个PictureBox
UpdatePictureBox(dogVideoBox, dogImage, false);
UpdatePictureBox(armVideoBox, armImage, true); // 机械臂视频需要旋转180度
}
}
catch (Exception ex)
{
Debug.WriteLine($"Error processing merged image data: {ex.Message}");
}
}
// 更新单个PictureBox的辅助方法
private void UpdatePictureBox(PictureBox pictureBox, Bitmap image, bool rotateImage)
{
if (pictureBox.InvokeRequired)
{
pictureBox.BeginInvoke(new Action(() =>
{
try
{
if (pictureBox.Image != null)
{
pictureBox.Image.Dispose();
}
Bitmap displayImage = new Bitmap(image);
if (rotateImage)
{
displayImage.RotateFlip(RotateFlipType.Rotate180FlipNone);
}
pictureBox.Image = displayImage;
pictureBox.Refresh();
}
catch (Exception ex)
{
Debug.WriteLine($"Error updating PictureBox: {ex.Message}");
}
}));
}
else
{
try
{
if (pictureBox.Image != null)
{
pictureBox.Image.Dispose();
}
Bitmap displayImage = new Bitmap(image);
if (rotateImage)
{
displayImage.RotateFlip(RotateFlipType.Rotate180FlipNone);
}
pictureBox.Image = displayImage;
pictureBox.Refresh();
}
catch (Exception ex)
{
Debug.WriteLine($"Error updating PictureBox: {ex.Message}");
}
}
}
// 原有的单独图像处理方法(保留兼容性)
public void ProcessImageData(PictureBox videoPictureBox, bool flag = false)
{
try
{
imageBuffer.Position = 0;
if (videoPictureBox.InvokeRequired)
{
videoPictureBox.BeginInvoke(new Action(() =>
{
try
{
if (videoPictureBox.Image != null)
{
videoPictureBox.Image.Dispose();
}
using (var tempImage = Image.FromStream(imageBuffer))
{
// 如果需要旋转则旋转180度
Bitmap displayedImage = new Bitmap(tempImage);
if (flag)
{
displayedImage.RotateFlip(RotateFlipType.Rotate180FlipNone);
}
// 显示图像
videoPictureBox.Image = displayedImage;
// 更新分辨率信息
videoWidth = displayedImage.Width;
videoHeight = displayedImage.Height;
}
videoPictureBox.Refresh();
}
catch (Exception ex)
{
// Handle any exceptions (e.g., image load failure)
Debug.WriteLine($"Error processing image: {ex.Message}");
}
}));
}
else
{
try
{
if (videoPictureBox.Image != null)
{
videoPictureBox.Image.Dispose();
}
using (var tempImage = Image.FromStream(imageBuffer))
{
Bitmap displayedImage = new Bitmap(tempImage);
if (flag)
{
displayedImage.RotateFlip(RotateFlipType.Rotate180FlipNone);
}
videoPictureBox.Image = displayedImage;
videoWidth = displayedImage.Width;
videoHeight = displayedImage.Height;
}
videoPictureBox.Refresh();
}
catch (Exception ex)
{
// Handle any exceptions (e.g., image load failure)
Debug.WriteLine($"Error processing image: {ex.Message}");
}
}
}
catch (Exception ex)
{
// Handle any outer exceptions
Debug.WriteLine($"Error processing image data: {ex.Message}");
}
}
}
}