用于串行传输的C#图像压缩

用于串行传输的C#图像压缩,c#,image,serial-port,compression,C#,Image,Serial Port,Compression,这是我的第一个问题,所以我希望提供它需要什么才能得到一个像样的答案 我想通过串行链接发送网络摄像头接收到的图像。 图像转换为字节数组,然后写入串行端口 我遇到的第一个问题是,当我试图发送图像时,它会导致TimeoutException。查看字节数组的长度,它向我显示了大约1MB需要传输的数据。缩小图像的实际大小会导致更快的传输,但之后图像就太小了 第二个isuue是当我试图压缩图像时。使用不同的方法,变速箱的尺寸总是完全相同的 我希望您能帮助我找到一种方法来改进我的实现,这样传输只需要几秒钟,同

这是我的第一个问题,所以我希望提供它需要什么才能得到一个像样的答案

我想通过串行链接发送网络摄像头接收到的图像。 图像转换为字节数组,然后写入串行端口

我遇到的第一个问题是,当我试图发送图像时,它会导致
TimeoutException
。查看字节数组的长度,它向我显示了大约1MB需要传输的数据。缩小图像的实际大小会导致更快的传输,但之后图像就太小了

第二个isuue是当我试图压缩图像时。使用不同的方法,变速箱的尺寸总是完全相同的

我希望您能帮助我找到一种方法来改进我的实现,这样传输只需要几秒钟,同时仍然保持图像的合理分辨率。谢谢


具体信息 网络摄像头图像
  • 来自网络摄像头的图像由AForge图书馆接收
  • 图像作为位图处理
  • (显然)它不会传输每一帧,只需点击一个按钮
串口
  • 端口使用57600 bps的波特率(由下面的硬件定义)
  • WriteTimeout
    -值设置为30秒,因为等待时间超过30秒是不可接受的
  • 文本传输使用WinForm中SerialPort项的默认值
图像处理 我使用了不同的方法来压缩图像:

简单的方法如

public static byte[] getBytes(Bitmap img)
{
    MemoryStream ms = new MemoryStream();
    img.Save(ms, System.Drawing.Imaging.ImageFormat.Jpeg);

    byte[] output = ms.toArray();
    ms.Dispose();
    return output;
}
以及更先进的方法,如张贴的方法。不仅使用
Encoder.Quality
,而且使用
Encoder.Compression

我的申请
将整个阵列拆分为几个较小的块并逐个发送是不是一个坏主意?

C挂起串行端口的timeout属性可以解决超时问题。如何在这个链接中显示。文件压缩的工作原理是查看数据块并将给定块段的相似块彼此关联。如果您的图像太独特,它将不会根据所使用的压缩软件进行压缩

图像的大小是多少?你缩略了多少?您的
getBytes
似乎在泄漏,压缩与质量只是表达相同内容的相反方式。你不能有高Q值和高压缩率。图像没有保存到磁盘上,所以我不能说出“文件大小”,但转换后的图像小于1MB。你的意思是泄漏,因为我没有关闭MemoryStream?我的意思是尺寸WxH;应该处理内存流。90比92比95的质量实际上在Size上有很大的区别。我回到电脑上时必须检查一下。网络摄像头拍摄800x600的照片,它们在“内部”发生了什么我真的不知道。当我得到它的时候,我会添加信息。GIF编码可能不是一件坏事——在宽带普及和负担得起之前,cams默认生成GIF。索引颜色可能意味着更少的数据这将解决
TimeoutException
,但会增加接收器端的工作量,传输总时间仍将远远超过30秒。如果您需要发送具有特定带宽的特定数据:S=V*t所以SizeOfData/bandwidth=Time。在理想情况下。如果你想把它放在时间限制下,并且由于它是串行端口,你的速度是有限的,唯一的方法就是通过尝试各种压缩设置来播放你的图片。这取决于你要发送的图像。
private void btn_Send(...)
{
    Bitmap currentFrame = getImageFromWebcam();
    
    //Bitmap sendFrame = new Bitmap(currentFrame, new Size(currentFrame.Width/10, currentFrame.Height/10));
    Bitmap sendFrame = compressImage(currentFrame);

    byte[] data = getBytes(sendFrame);

    serialPort.Write(data, 0, data.Lenght);
}