问题
I am trying to write BMP image class with reading method. I saw msdn specification of BMP files, so I try to read the headers and after, using the biHeight and biWidth information, read RGB info of every pixel. So, it don't read header information, the value of every header parameter is -1.
Here's code:
#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;
}
}
P.S. Thank you everybody for help
回答1:
The member
ifstream pFile;
of class BMPImage is not being initialized, so when you use it in member functions it isn't valid. Instead you are locally defining a different pFile instance in the constructor. These should probably be the same instance.
回答2:
I think you should change this:
typedef struct
{
int rgbBlue;
int rgbGreen;
int rgbRed;
int rgbReserved;
} RGBColor;
For this:
typedef struct
{
unsigned char rgbBlue;
unsigned char rgbGreen;
unsigned char rgbRed;
unsigned char rgbReserved;
} RGBColor;
Reference: https://msdn.microsoft.com/en-us/library/windows/desktop/dd162938(v=vs.85).aspx
来源:https://stackoverflow.com/questions/22112412/reading-bmp-file-c-trouble-with-reading-bmp-header