读取 BMP 文件 C++(读取 BMP 标头时出现问题)
Posted
技术标签:
【中文标题】读取 BMP 文件 C++(读取 BMP 标头时出现问题)【英文标题】:Reading BMP file C++ (trouble with reading BMP header) 【发布时间】:2014-03-01 09:15:45 【问题描述】:我正在尝试使用阅读方法编写 BMP 图像类。我看到了 BMP 文件的 msdn 规范,所以我尝试读取标题,然后使用 biHeight 和 biWidth 信息读取每个像素的 RGB 信息。 所以,它不读取头信息,每个头参数的值都是-1。
代码如下:
#ifndef BMP_IMAGE_H
#define BMP_IMAGE_H
#include <fstream>
using namespace std;
typedef struct
unsigned int bfType;
unsigned long bfSize;
unsigned int bfReserved1;
unsigned int bfReserved2;
unsigned long bfOffBits;
BitMapFileHeader;
typedef struct
unsigned int biSize;
int biWidth;
int biHeight;
unsigned short biPlanes;
unsigned short biBitCount;
unsigned int biCompression;
unsigned int biSizeImage;
int biXPelsPerMeter;
int biYPelsPerMeter;
unsigned int biClrUsed;
unsigned int biClrImportant;
BitMapInfoHeader;
typedef struct
int rgbBlue;
int rgbGreen;
int rgbRed;
int rgbReserved;
RGBColor;
class BMPImage
private:
unsigned short read_u16();
unsigned int read_u32();
int read_s32();
public:
ifstream pFile;
int imageWidth;
int imageHeight;
RGBColor **rgb;
BMPImage(char* fileName);
void pixelsInfo();
;
#endif // BMP_IMAGE_H
#include "bmp_image.h"
#include <iostream>
using namespace std;
BMPImage::BMPImage(char* fileName)
ifstream pFile(fileName, ios::in | ios::binary);
// read the header of file
BitMapFileHeader header __attribute__((unused));
header.bfType = read_u16();
header.bfSize = read_u32();
header.bfReserved1 = read_u16();
header.bfReserved2 = read_u16();
header.bfOffBits = read_u32();
// read the header of image
BitMapInfoHeader bmiHeader;
bmiHeader.biSize = read_u32();
bmiHeader.biWidth = read_s32();
bmiHeader.biHeight = read_s32();
bmiHeader.biPlanes = read_u16();
bmiHeader.biBitCount = read_u16();
bmiHeader.biCompression = read_u32();
bmiHeader.biSizeImage = read_u32();
bmiHeader.biXPelsPerMeter = read_s32();
bmiHeader.biYPelsPerMeter = read_s32();
bmiHeader.biClrUsed = read_u32();
bmiHeader.biClrImportant = read_u32();
cout << (int)bmiHeader.biHeight <<"\n";
RGBColor **rgb = new RGBColor*[bmiHeader.biHeight];
for (int i = 0; i < bmiHeader.biWidth; i++)
rgb[i] = new RGBColor[bmiHeader.biHeight];
for (int i = 0; i < bmiHeader.biWidth; i++)
for (int j = 0; j < bmiHeader.biHeight; j++)
rgb[i][j].rgbBlue = pFile.get();
rgb[i][j].rgbGreen = pFile.get();
rgb[i][j].rgbRed = pFile.get();
char temp;
pFile.get(temp);
imageWidth = bmiHeader.biWidth;
imageHeight = bmiHeader.biHeight;
pFile.close();
unsigned short BMPImage::read_u16()
unsigned char b0, b1;
b0 = pFile.get();
b1 = pFile.get();
return ((b1 << 8) | b0);
unsigned int BMPImage::read_u32()
unsigned char b0, b1, b2, b3;
b0 = pFile.get();
b1 = pFile.get();
b2 = pFile.get();
b3 = pFile.get();
return ((((((b3 << 8) | b2) << 8) | b1) << 8) | b0);
int BMPImage::read_s32()
unsigned char b0, b1, b2, b3;
b0 = pFile.get();
b1 = pFile.get();
b2 = pFile.get();
b3 = pFile.get();
return ((int)(((((b3 << 8) | b2) << 8) | b1) << 8) | b0);
void BMPImage::pixelsInfo()
for (int i = 0; i < imageWidth; i++)
for (int j = 0; j < imageHeight; j++)
std::cout << rgb[i][j].rgbRed <<" " << rgb[i][j].rgbGreen << " " << rgb[i][j].rgbBlue << std::endl;
std::cout << std::endl;
附:谢谢大家的帮助
【问题讨论】:
检查文件是否打开成功。 if(!pFile) 错误... 您没有初始化 pFile 类成员。您的构造函数声明了一个本地 pFile(这意味着您的所有读取例程使用的 pFile 都是无效的)。 这是我的第一件事,但这不是原因,文件已被安全打开 用pFile.Open(fileName, ios::in | ios::binary);
替换ifstream pFile(fileName, ios::in | ios::binary);
aselle,谢谢,这是个问题
【参考方案1】:
会员
ifstream pFile;
类 BMPImage 没有被初始化,所以当你在成员函数中使用它时它是无效的。相反,您在构造函数中本地定义不同的 pFile 实例。这些应该是同一个实例。
【讨论】:
我想说@aselle 的评论应该作为答案提出来!【参考方案2】:我认为你应该改变这个:
typedef struct
int rgbBlue;
int rgbGreen;
int rgbRed;
int rgbReserved;
RGBColor;
为此:
typedef struct
unsigned char rgbBlue;
unsigned char rgbGreen;
unsigned char rgbRed;
unsigned char rgbReserved;
RGBColor;
参考:https://msdn.microsoft.com/en-us/library/windows/desktop/dd162938(v=vs.85).aspx
【讨论】:
以上是关于读取 BMP 文件 C++(读取 BMP 标头时出现问题)的主要内容,如果未能解决你的问题,请参考以下文章