如何将海康威视RGB8格式彩色相机图像正确显示到PictureBox
修正海康威视RGB8彩色相机图像显示问题
问题原因
原代码针对8bpp索引灰度格式编写,切换到RGB8(24bpp真彩色)相机时,会触发两个核心错误:
- 把3字节的RGB像素数据当成1字节的索引数据解析,每个像素仅读取1/3字节,剩余字节被错误识别为下一个像素,导致条纹出现。
- 强制设置灰度调色板,即使存在彩色数据也会被转换为灰度显示。
解决方案
修改Bitmap创建参数适配RGB8格式,同时移除不必要的调色板操作:
- 替换像素格式:将
PixelFormat.Format8bppIndexed改为PixelFormat.Format24bppRgb(海康彩色相机多数输出BGR24格式,与Windows Bitmap的存储顺序匹配)。 - 修正扫描线宽度:24bpp格式要求每行字节数为4的倍数,计算公式为
((宽度 * 3) + 3) & ~3;若海康帧信息提供了扫描线宽度字段(如stFrameInfo.nStride),优先使用该字段。 - 移除调色板代码:24bpp为真彩色格式,无需索引调色板,直接显示即可。
修正后的完整代码
using (Bitmap bmp1 = new Bitmap( stFrameInfo.stFrameInfo.nWidth, stFrameInfo.stFrameInfo.nHeight, // 计算24bpp对齐扫描线宽度,或替换为stFrameInfo.nStride(如果存在) ((stFrameInfo.stFrameInfo.nWidth * 3) + 3) & ~3, PixelFormat.Format24bppRgb, stFrameInfo.pBufAddr)) { this.Invoke((MethodInvoker)delegate { imageBox1.Image = bmp1; }); }
额外注意事项
若显示后出现红蓝色反转,说明相机输出的是RGB字节顺序而非BGR,可通过ColorMatrix调整色彩通道:
using (Bitmap bmp1 = new Bitmap( stFrameInfo.stFrameInfo.nWidth, stFrameInfo.stFrameInfo.nHeight, ((stFrameInfo.stFrameInfo.nWidth * 3) + 3) & ~3, PixelFormat.Format24bppRgb, stFrameInfo.pBufAddr)) using (Bitmap correctedBmp = new Bitmap(bmp1.Width, bmp1.Height)) using (Graphics g = Graphics.FromImage(correctedBmp)) { // 交换R和B通道的ColorMatrix ColorMatrix colorMatrix = new ColorMatrix(new float[][] { new float[] {0, 0, 1, 0, 0}, new float[] {0, 1, 0, 0, 0}, new float[] {1, 0, 0, 0, 0}, new float[] {0, 0, 0, 1, 0}, new float[] {0, 0, 0, 0, 1} }); ImageAttributes attributes = new ImageAttributes(); attributes.SetColorMatrix(colorMatrix); g.DrawImage(bmp1, new Rectangle(0, 0, bmp1.Width, bmp1.Height), 0, 0, bmp1.Width, bmp1.Height, GraphicsUnit.Pixel, attributes); this.Invoke((MethodInvoker)delegate { imageBox1.Image = correctedBmp; }); }
内容的提问来源于stack exchange,提问作者Starscream
相关产品推荐
相关产品推荐

