用c++风格和C风格写一个bmp-header

Writing a bmp-header in C++ style vs C style

本文关键字:风格 一个 bmp-header c++      更新时间:2023-10-16

很久以前,我用C写了一个函数来写bmp-header。我使用二进制运算符将uint_16和uint_32直接解析为char[54]数组,这可以照顾到端序和可移植性。

我已经学习c++有一段时间了,现在我正试图用std::ofstream代替FILE*来用c++风格重写这个函数。我编写的c++代码看起来很糟糕,而且没有处理尾序。是否有更好或更合适的方法来处理c++头文件?(最好是可移植的,并且可以处理尾序)

当前是这样的:

void writeHeader(int width, int height, std::ofstream file)
{
    char bmpSign[2] = {'B', 'M'};
    uint filesize = width*height*3+54;
    uint reserved = 0;
    uint headersize = 54;
    uint infoHeader = 40;
    ushort colors = 1;
    ushort bitsPerPixel = 24;
    uint compression = 0;
    uint imgSize = width*height*3;
    uint xPels = 0;
    uint yPels = 0;
    uint usedColors = 0;
    uint impColors = 0;
    file.write(bmpSign, 2*sizeof(char));
    file.write(reinterpret_cast<char*>(filesize),     sizeof(int));
    file.write(reinterpret_cast<char*>(reserved),     sizeof(int));
    file.write(reinterpret_cast<char*>(headersize),   sizeof(int));
    file.write(reinterpret_cast<char*>(infoHeader),   sizeof(int));
    file.write(reinterpret_cast<char*>(width),        sizeof(int));
    file.write(reinterpret_cast<char*>(height),       sizeof(int));
    file.write(reinterpret_cast<char*>(colors),       sizeof(ushort));
    file.write(reinterpret_cast<char*>(bitsPerPixel), sizeof(ushort));
    file.write(reinterpret_cast<char*>(compression),  sizeof(int));
    file.write(reinterpret_cast<char*>(imgSize),      sizeof(int));
    file.write(reinterpret_cast<char*>(xPels),        sizeof(int));
    file.write(reinterpret_cast<char*>(yPels),        sizeof(int));
    file.write(reinterpret_cast<char*>(usedColors),   sizeof(int));
    file.write(reinterpret_cast<char*>(impColors),    sizeof(int));
}

谢谢!

标题的c版本:

void parseInt16(uint16_t mem_head, uint8_t file_head[54], int offset)
{
  file_head[offset] = (mem_head & 0x00ff);
  file_head[offset + 1] = (mem_head & 0xff00) >> 8;
}
void parseInt32(uint32_t mem_head, uint8_t file_head[54], int offset) 
{   
  file_head[offset] = (mem_head & 0x000000ff);
  file_head[offset + 1] = (mem_head & 0x0000ff00) >> 8;
  file_head[offset + 2] = (mem_head & 0x00ff0000) >> 16;
  file_head[offset + 3] = (mem_head & 0xff000000) >> 24;
}
void writeHeader(int width, int height, FILE* bitmap_destination)
{
  uint8_t bmp_header[54];
  bmp_header[0] = 'B'; bmp_header[1] = 'M'; 
  //parsing the 32 or 16 bit numbers into byte form, little-endian.
  //function syntax: (value, Array of Bytes, Offset)
  parseInt32(width * height * 3 + 54, bmp_header, 2); //filesize
  parseInt32(0, bmp_header, 6);                   //reserved by software (0)
  parseInt32(54, bmp_header, 10 );                //headerOffset / Header size
  parseInt32(40, bmp_header, 14 );                    //infoHeaderSize
  parseInt32(width, bmp_header, 18);              //Width in pixels
  parseInt32(height, bmp_header, 22);             //Height in pixels
  parseInt16(1, bmp_header, 26);                  //Colors (1 per standard)
  parseInt16(24, bmp_header, 28);                 //bitsPerPixel (3 bytes/p)
  parseInt32(0, bmp_header, 30);                  //Compression (0 = none)
  parseInt32(width * height * 3, bmp_header, 34); //Image Size(bytes)
  parseInt32(0, bmp_header, 38);                  //xPelsPerMeter
  parseInt32(0, bmp_header, 42);                  //yPelsPerMeter
  parseInt32(0, bmp_header, 46);                  //Colors used (0 for all)
  parseInt32(0, bmp_header, 50);                  //important Colors (0 for all)
  fwrite(bmp_header, 1, 54, bitmap_destination); //writing the header to disk
}

处理平台端序的代码应该被重用。该代码与您使用FILE*还是std::fstream来写入数据无关。

唯一需要修改的行是

fwrite(bmp_header, 1, 54, bitmap_destination); 

可以替换为:

file.write(reinterpret_cast<char*>(bmp_header), 54);