我正在尝试读取 .bmp 文件头并将其显示到控制台输出。
我有两种 .bmp 头部信息结构:
struct bmp_header{
uint16_t bmp_file_code{0x424D}; // BMP format code always 0x424D
uint32_t bmp_file_size{0}; // Whole file size
uint32_t application_data{0}; // Generally unused
uint32_t pixel_offset{0}; // Offset to pixel array
};
struct bmp_dib_header{
uint32_t dib_head_size; // In bytes. Size of DIB header.
uint32_t image_width; // In pixels
uint32_t image_height; // In pixels
uint16_t color_planes;
uint16_t bits_per_pixel;
uint32_t compression_method; // Compression type code
uint32_t image_size; // In bytes. width * heigth * color channels count
int32_t x_resolution; // In pixels per metre
int32_t y_resolution; // In pixels per metre
uint32_t color_palette; // Number of colors used (default 0 is 2^n)
uint32_t important_colors; // Number of important colors (generally ignored)
};
读取方法如下:
void read_header(std::ifstream &filestream) {
auto end = filestream.tellg();
filestream.seekg(0, std::ios_base::beg);
if (end - filestream.tellg() <= 0) throw std::runtime_error(strerror(errno));
// Read HEAD
filestream.read(reinterpret_cast<char*>(&bmp_head), sizeof(bmp_header));
// Read Info (DIB-header)
filestream.read(reinterpret_cast<char*>(&bmp_dib), sizeof(bmp_dib_header));
}
fileastream
用 std::ios_base::binary
和 std::ios_base::in
打开
输出函数为:
void debug_show_header_info() {
std::cout << "BMP head data:" << std::endl \
<< "File code: " << std::hex << bmp_head.bmp_file_code << std::endl \
<< "File size: " << std::hex << bmp_head.bmp_file_size << std::endl \
<< "Application data: " << std::hex << bmp_head.application_data << std::endl \
<< "Pixel offset: " << std::hex << bmp_head.pixel_offset << std::endl;
}
在十六进制编辑器中我有这个: 在此输入图片描述
程序给我这个:
BMP head data:
File code: 4d42
File size: c <<< This is not true (0x528F0C actually)
Application data: 8a0000
Pixel offset: 7c0000
看起来程序跳过了一些字节(格式代码后的 4 个字节和文件大小后的 4 个字节),我觉得很愚蠢,因为不知道为什么会发生这种情况。预先感谢。
我尝试一一读取值。同样的结果。
UPD 这是最小问题示例 部分代码:https://pastebin.com/W5P9jtGL 图片是
sample1.bmp
来自此网站:https://filesampleshub.com/format/image/bmp
sizeof(bmp_head)
是 10 个字节,而不是应该是 14 个字节。
这导致了结构对齐。
这对我有帮助:
#pragma pack(2) // Pack structures by 2 bytes