用C ++风格和C风格编写bmp-header

时间:2015-07-31 16:35:17

标签: c++

很久以前我在C中写了一个写一个bmp-header的函数。我使用二元运算符将uint_16和uint_32直接解析为char [54]数组,该数组负责字节序和可移植性。

我已经学习了一段时间的C ++,现在我正在尝试用C ++重写该函数 - 使用std :: ofstream代替FILE *。我制作的c ++代码看起来很糟糕,并没有处理endianess。有没有更好的,或更恰当的方式来做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
}

1 个答案:

答案 0 :(得分:3)

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

您需要更改的唯一一行是

fwrite(bmp_header, 1, 54, bitmap_destination); 

可以替换为:

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