Files
ArmDogControl/DogAndArmControl/VideoCaltulate.cs
2025-10-13 16:34:23 +08:00

334 lines
14 KiB
C#
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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}");
}
// 处理合并后的图像数据并分割显示
await Task.Run(() => ProcessMergedImageData(dogVideoBox, armVideoBox));
//await Task.Run(() => ProcessImageData(armVideoBox));
}
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}");
}
}
}
}