C++ 如何使用C++;?

C++ 如何使用C++;?,c++,bitmap,C++,Bitmap,我试图通过使用从struct BitMapInfo Header收集的信息来计算BMP图像中的像素数,从而计算每个像素的字节数。但每当我运行代码时,我得到的每像素字节数=0 struct BITMAPFILEHEADER // File header { char bfType[2]; // File type: should be BM ( 0x42 0x4D ) int bfSize;

我试图通过使用从struct BitMapInfo Header收集的信息来计算BMP图像中的像素数,从而计算每个像素的字节数。但每当我运行代码时,我得到的每像素字节数=0

struct BITMAPFILEHEADER             // File header
{
char bfType[2];                   // File type: should be BM ( 0x42 0x4D ) 
int bfSize;                       // File size in bytes
short bfReserved1;                // Reserved - for what i have no idea :P 
short bfReserved2;                // -||-
int bfOffBits;                    // Offset, adress of the beginning of the information about image (pixels )
};

struct BITMAPINFOHEADER             // Bitmap header
{
unsigned int biSize;              // Size of this header
unsigned int biWidth;             // Width of image ( in pixels)
unsigned int biHeight;            // Height of this image ( in pixels )
unsigned short biPlanes;          // Numer of color planes, always 1
unsigned short biBitCount;        // Number of bytes for pixel.  Possibility values :1,4,8,16, 24 and 32
unsigned int biCompression;       // Used compression (0 -none)
unsigned int biSizeImage;         // Size of image 
signed int biXPelsPerMeter;       // Horizontal resolution of the image (pixel per meter)
signed int biYPelsPerMeter;       // Vertical resolution of the image (pixel per meter)
unsigned int biClrUsed;           // Number of colors in the color palette, or 0 to default to 2^n ( 0- no palette)
unsigned int biClrImportant;      // Number of important colors used
 };

struct Pixel{
unsigned int blue;  // or double?
unsigned int green;
unsigned int red;
//unsigned char reserved;
};


void Image::conversiontoBRG(const char* filename)
{
ifstream brgfile;
brgfile.open(filename, ios::in | ios::binary);


char *bmpheadinfo = new char[sizeof(BITMAPFILEHEADER)];
brgfile.read(bmpheadinfo, sizeof(BITMAPFILEHEADER));
BITMAPFILEHEADER* bmpheader = (BITMAPFILEHEADER*)bmpheadinfo;

cout << "File type : " << bmpheader->bfType << endl;
cout << "File size : " << bmpheader->bfSize << endl;
cout << "File Offset for the beginning of image info : " << bmpheader->bfOffBits << endl << endl;


bmpheadinfo = new char[sizeof(BITMAPINFOHEADER)];
brgfile.read(bmpheadinfo, sizeof(BITMAPINFOHEADER));
BITMAPINFOHEADER* bmpinfo = (BITMAPINFOHEADER*)bmpheadinfo;

cout << "File Header Size : " << bmpinfo->biSize << endl;
cout << "Width : " << bmpinfo->biWidth << endl;
cout << "Height : " << bmpinfo->biHeight << endl;
cout << "No of bytes per pixel : " << bmpinfo->biBitCount << endl;
cout << "Used compression: " << bmpinfo->biCompression << endl;
cout << "Image size: " << bmpinfo->biSizeImage << endl;
cout << "Horizontal resolution: " << bmpinfo->biXPelsPerMeter << endl;
cout << "Vertical resolution: " << bmpinfo->biYPelsPerMeter << endl;
cout << "Number of colors in the color palette: " << bmpinfo->biClrUsed << endl;
cout << "Number of important colors used: " << bmpinfo->biClrImportant << endl;
}

BMP文件在头数据中没有填充位,而您的
struct
s已定义为没有紧密打包宏;这将导致文件数据成员和
struct
数据成员未正确对齐。修复此问题,您将能够正确地看到字段

#pragma pack(push, 1)       // macro to avoid padding bytes within a struct

struct BITMAPFILEHEADER             // File header
{
    char bfType[2];                   // File type: should be BM ( 0x42 0x4D ) 
    int bfSize;                       // File size in bytes
    short bfReserved1;                // Reserved - for what i have no idea :P 
    short bfReserved2;                // -||-
    int bfOffBits;                    // Offset, adress of the beginning of the information about image (pixels )
};

struct BITMAPINFOHEADER             // Bitmap header
{
    unsigned int biSize;              // Size of this header
    unsigned int biWidth;             // Width of image ( in pixels)
    unsigned int biHeight;            // Height of this image ( in pixels )
    unsigned short biPlanes;          // Numer of color planes, always 1
    unsigned short biBitCount;        // Number of bytes for pixel.  Possibility values :1,4,8,16, 24 and 32
    unsigned int biCompression;       // Used compression (0 -none)
    unsigned int biSizeImage;         // Size of image 
    signed int biXPelsPerMeter;       // Horizontal resolution of the image (pixel per meter)
    signed int biYPelsPerMeter;       // Vertical resolution of the image (pixel per meter)
    unsigned int biClrUsed;           // Number of colors in the color palette, or 0 to default to 2^n ( 0- no palette)
    unsigned int biClrImportant;      // Number of important colors used
};

#pragma pack(pop)         // stop doing the tight packing
现在可以确认没有填充位

std::cout << sizeof BITMAPFILEHEADER << '\n';

std::cout以及包装问题legends2k提到:

  • 你没有考虑endianness(谷歌搜索它,然后在你的代码中使用
    ntohs
    等)

  • 您应该创建一个本地
    位图文件头bmpheader对象然后
    brgfile.read((char*)&bmpheader,bmpheader的大小)-这样您就知道嵌入的多字节整数将正确对齐以便访问-否则您可能会在某些系统上得到SIGBUS或类似的结果;对
    BitMapInfo头执行类似操作


  • 也不要只打印
    bfType
    ——作为一个数组,它会衰减为
    const char*
    ,因为
    12058624是0xB80000。0xB8是184。18022400是0x1130000。0x113是275。你不同步。
    BMVS
    是以大端十六进制表示的0x424d5653。字符串
    VS
    之所以出现,是因为
    bfType
    不像TonyD说的那样是以null结尾的字符串,它是
    bfSize
    的2个MSB。由于没有指定填充,因此对齐
    bfSize
    从下一个4字节边界开始,并在大端字节中读取2或0x02000000。因此,它的实际值是
    0x00025356=152406字节=148.834KB
    只需使用
    #pragma pack(push,1)
    #pragma pack(pop)
    宏即可。您将得到您期望的结果。@PureProgrammer已经由legends2k回答过了,不,它将不起作用,因为它只解决了系统中的一个问题code@L对不起,我没有想到这一点。但是,我认为
    bfType
    应该是
    无符号短的类型
    对吗?由于忽略填充字节时会导致未对齐的访问,因此对metoning SIGBUS进行了上浮表决。
    std::cout << sizeof BITMAPFILEHEADER << '\n';