如何用RabbitMQ+Protocol Buffer实现C++到C#的图像传输?
解答你的RabbitMQ + Protobuf图像传输问题
Hey there! Let's work through your questions about sending OpenCV images from C++ to C# using RabbitMQ and Protocol Buffers.
1. 应该转成字节数组还是字符串?
绝对选字节数组,原因很简单:图像是二进制数据,转成字符串(比如UTF-8)会因为编码规则破坏原始二进制内容——很多字节值不是合法的UTF-8字符,转字符串再转回来会丢失或损坏数据。
你的.proto文件里已经把Image字段定义成bytes类型,这完全符合需求,它就是Protobuf专门用来存储二进制数据的类型,完美适配图像这类二进制内容。
在C++里,你可以通过OpenCV的imencode函数把cv::Mat转换成字节数组(std::vector<uchar>),然后直接赋值给Protobuf生成的LPRResult的Image字段。示例代码:
// 读取图像到Mat cv::Mat img = cv::imread("test.jpg"); if (img.empty()) { /* 处理读取失败 */ } // 把Mat编码成字节数组(这里用PNG格式,也可以选JPG,注意和C#端解码一致) std::vector<uchar> imgBuffer; cv::imencode(".png", img, imgBuffer); // 填充Protobuf消息 ProtoBufLPR::LPRResult lprResult; lprResult.set_licencseplate("XYZ-123"); // 注意你的proto里字段名拼写是LicencsePlate(少了个s),如果是笔误建议修正 lprResult.set_image(std::string(imgBuffer.begin(), imgBuffer.end())); // 序列化后发送到RabbitMQ...
2. C#项目中如何声明对应类型?
只要你用Protobuf的编译器(protoc)生成C#代码,就不需要手动声明类型——生成的LPRResult类会自动把Image字段映射为byte[](C#的字节数组类型),完全匹配Protobuf的bytes定义。
接收并转换图像的示例代码(用OpenCVSharp为例,你也可以用Emgu CV):
// 从RabbitMQ接收序列化后的Protobuf字节数组 byte[] receivedProtoBytes = ...; // 解析Protobuf消息 var lprResult = ProtoBufLPR.LPRResult.Parser.ParseFrom(receivedProtoBytes); // 把byte[]转成OpenCV Mat using (var memoryStream = new MemoryStream(lprResult.Image)) { var img = OpenCvSharp.Mat.FromStream(memoryStream, OpenCvSharp.ImreadModes.Color); // 在这里处理图像,比如显示、识别等 }
小提醒
- 注意你
.proto里的字段名拼写:LicencsePlate应该是LicensePlate(正确拼写是License),如果是笔误建议修正,避免后续代码里的字段名混淆。 - 编码格式要统一:C++端
imencode用的格式(比如.png)要和C#端解码时的格式匹配,不然会无法正确解析图像。
内容的提问来源于stack exchange,提问作者Trying_To_Understand
相关产品推荐
相关产品推荐

