334 lines
14 KiB
C#
334 lines
14 KiB
C#
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}");
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|