在 C# 中从 char[] 缓冲区创建位图
我必须将我的 C++ 项目与 C# 项目连接起来,并通过命名管道向其发送图像。 OpenCV 将矩阵数据存储在连续的块中,从 uchar* Mat::data
开始。但是,要通过命名管道发送数据,它必须是 char*
,所以我只是进行了强制转换,不知道还应该做什么。没关系,这只是数据,而不是字符。
size_t s = frame2.elemSize() * frame2.rows * frame2.cols;
sendChars(hPipe, (char*)frame2.data, s);
在 C# 方面,我将数据块读入 char[]
缓冲区。然后,我创建一个具有适当宽度、高度等的新位图,并将 IntPtr 设置为 char[] 缓冲区的开头。
//in the C# forms private scope:
char[] buffer = new char[921600];
然后在 StartServer()
函数中:
pipeServer = new NamedPipeServerStream("SamplePipe", PipeDirection.InOut);
//blah blah blah
using (StreamReader sr = new StreamReader(pipeServer))
{
sr.ReadBlock(buffer, 0, buffer.Length);
unsafe
{
fixed (char* ptr = buffer)
{
using (Bitmap image = new Bitmap(640, 480, 640*3, PixelFormat.Format24bppRgb, new IntPtr(ptr)))
{
pictureBox1.Image = image;
image.Save("test.png");
}
}
}
}
结果是 C# 表单上出现一个红色的大 X,并且保存的图像看起来乱码......但不仅仅是随机噪声。因此,数据在传输前的 C++ 端或在解释时的 C# 端都会出现混乱。我尝试通过使用位图构造函数来解决此问题,该构造函数读取流并发送编码图像而不是原始像素,但这比上述方法更失败(仅给出错误,没有输出)。
如何将带有像素数据的 uchar* 数组从 C++ 传输到 C#,然后在位图中重建它,以便我可以显示在表格上吗?
I've got to interface my C++ project with a C# project and send an image to it across a named pipe. OpenCV stores matrix data in a contiguous chunk, starting at uchar* Mat::data
. However, to send data across a named pipe, it must be a char*
, so I just do a cast, not sure what else I'm supposed to do. It shouldn't matter, it's just data, not characters.
size_t s = frame2.elemSize() * frame2.rows * frame2.cols;
sendChars(hPipe, (char*)frame2.data, s);
On the C# side I read in the block of data to a char[]
buffer. I then create a new Bitmap
with the appropriate width, height, etc. and set the IntPtr to the beginning of the char[] buffer
.
//in the C# forms private scope:
char[] buffer = new char[921600];
and then in a StartServer()
function:
pipeServer = new NamedPipeServerStream("SamplePipe", PipeDirection.InOut);
//blah blah blah
using (StreamReader sr = new StreamReader(pipeServer))
{
sr.ReadBlock(buffer, 0, buffer.Length);
unsafe
{
fixed (char* ptr = buffer)
{
using (Bitmap image = new Bitmap(640, 480, 640*3, PixelFormat.Format24bppRgb, new IntPtr(ptr)))
{
pictureBox1.Image = image;
image.Save("test.png");
}
}
}
}
The result of this is a big red X on the C# form and the saved image looks garbled... but not just random noise. So the data's coming through and getting messed up either on the C++ end before transmission or the C# end on interpretation. I have tried to work around this by using the Bitmap constructor that reads a stream and sending an encoded image instead of the raw pixels, but that fails harder than the above method (just gives an error, no output).
How do I transfer uchar* array with pixel data from C++ to C# and then reconstruct it inside a Bitmap so that I can display it on the form?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
如果您发送的实际上是二进制数据,那么在这里使用
StreamReader
似乎是错误的选择。 StreamReader 用于读取文本,并将数据解码为具有某种编码的字符,在您的情况下,该编码将被自动检测(并且肯定是错误的)。您想要使用
BinaryReader
读取二进制数据,或者使用Read()
方法直接从NamedPipeServerStream
读取以获取byte[]
数组。 C#中的char
用于存储字符,并且是unicode,而不是单个字节。The use of a
StreamReader
here seems like the wrong choice if what you're sending is actually binary data. TheStreamReader
is used for reading text, and will decode the data to characters with some encoding which in your case would be auto-detected (and definitely wrong).You want to use the
BinaryReader
for reading binary data, or read directly from theNamedPipeServerStream
using theRead()
method to get abyte[]
array. Achar
in C# is used for storing characters, and is unicode, not a single byte.如果您使用流,最简单的方法是使用 Bitmap 的 SetPixel 方法来构造图像。
If you use stream the easiest way would be to use the SetPixel method of Bitmap to construct the image.