如何在PictureBox中显示.raw格式图像?代码报参数错误求排查
解决Raw格式转Bitmap并显示的参数错误问题
代码中的核心问题
- 拼写错误直接引发参数错误:代码里
PixelFormap.Format16bppGrayScale是笔误,正确写法为PixelFormat.Format16bppGrayScale,这是触发参数错误的直接原因之一。 - 16位灰度图的像素逻辑错误:
Format16bppGrayScale每个像素占2字节,但你在unsafe块里每次只写入1字节;同时width的计算逻辑有误——samples如果是像素宽度,那Bitmap构造的width参数应该是samples(像素数),而非samples*bytePixel(字节数)。 - 扫描行字节对齐问题:GDI+的Bitmap要求每行字节数必须是4的倍数(即stride为4的整数倍),直接按
width*2逐字节写入会导致内存越界或图像显示异常。 - 冗余的二维数组拷贝:把raw字节数组转成二维数组完全没必要,既浪费内存又拖慢效率,直接操作原数组即可。
- 变量初始化错误:
int counter = new int();是错误的初始化方式,应改为int counter = 0;。
修正后的代码
string filename = @"test.raw"; byte[] rawBytes = File.ReadAllBytes(filename); int bytePerPixel = 2; // samples是图像的像素宽度,lines是像素高度 int pixelWidth = samples; int pixelHeight = lines; // 创建16位灰度格式的Bitmap Bitmap bitmapImage = new Bitmap(pixelWidth, pixelHeight, PixelFormat.Format16bppGrayScale); BitmapData bitmapData = bitmapImage.LockBits( new Rectangle(0, 0, pixelWidth, pixelHeight), ImageLockMode.WriteOnly, PixelFormat.Format16bppGrayScale); unsafe { byte* basePtr = (byte*)bitmapData.Scan0.ToPointer(); int stride = bitmapData.Stride; // 获取Bitmap实际每行的字节数(已自动对齐到4的倍数) int rawIndex = 0; for (int y = 0; y < pixelHeight; y++) { byte* rowPtr = basePtr + y * stride; for (int x = 0; x < pixelWidth; x++) { // 写入16位像素的两个字节,若图像显示异常,可交换两个字节的顺序(适配raw数据的字节序) rowPtr[x * bytePerPixel] = rawBytes[rawIndex]; rowPtr[x * bytePerPixel + 1] = rawBytes[rawIndex + 1]; rawIndex += bytePerPixel; } } } bitmapImage.UnlockBits(bitmapData); pictureBox1.Image = bitmapImage;
额外注意事项
- 确认raw数据的字节序(小端/大端),如果图像显示异常,交换两个字节的写入顺序即可。
- 确保
samples和lines的取值正确,且rawBytes总长度等于samples * lines * bytePerPixel,避免数组越界。 - 项目需要开启允许不安全代码选项(在项目属性→生成→勾选"允许不安全代码")。
内容的提问来源于stack exchange,提问作者bsg
相关产品推荐
相关产品推荐

