RBr*_*ght 4 c++ syntax bmp bitmapimage
我遇到了这种在 C++ 中读取 BMP 文件的语法
#include <fstream>
int main() {
std::ifstream in('filename.bmp', std::ifstream::binary);
in.seekg(0, in.end);
size = in.tellg();
in.seekg(0);
unsigned char * data = new unsigned char[size];
in.read((unsigned char *)data, size);
int width = *(int*)&data[18];
// omitted remainder for minimal example
}
Run Code Online (Sandbox Code Playgroud)
我不明白线路是什么
int width = *(int*)&data[18];
Run Code Online (Sandbox Code Playgroud)
实际上是在做。为什么从unsigned char *to int, int width = (int)data[18];,的简单转换不起作用?
笔记
正如@user4581301在评论中指出的那样,这取决于实现,并且在许多情况下会失败。正如@NathanOliver- Reinstate Monica和@ChrisMM指出的那样,这是未定义的行为,无法保证结果。
根据位图头格式,位图的宽度以像素为单位存储为一个有符号的 32 位整数,从字节偏移量 18 开始。语法
int width = *(int*)&data[18];
Run Code Online (Sandbox Code Playgroud)
读取字节 19 到 22,包括(假设为 32 位int)并将结果解释为整数。
&data[18]获取unsigned char索引 18 处的地址(int*)将地址从 转换unsigned char*为int*以避免在 64 位体系结构上丢失精度*(int*)取消引用地址以获取引用int值所以基本上,它获取地址data[18]并读取该地址处的字节,就好像它们是一个整数一样。
sizeof(data[18])是1,因为unsigned char是一个字节(0- 255),但sizeof(&data[18])是4,如果系统是32位和8如果它是64位,这可以是更大的(或甚至为16位系统更小),但用16位系统中,外应该是最小4字节数。显然,4在这种情况下不希望读取多于字节,并且转换为(int*)和随后的取消引用会int产生4字节,实际上是偏移量 18 和 21 之间的 4 个字节,包括这两个字节。一个简单的从unsigned charto 转换int也将产生 4 个字节,但只有一个字节的信息来自data. 以下示例说明了这一点:
#include <iostream>
#include <bitset>
int main() {
// Populate 18-21 with a recognizable pattern for demonstration
std::bitset<8> _bits(std::string("10011010"));
unsigned long bits = _bits.to_ulong();
for (int ii = 18; ii < 22; ii ++) {
data[ii] = static_cast<unsigned char>(bits);
}
std::cout << "data[18] -> 1 byte "
<< std::bitset<32>(data[18]) << std::endl;
std::cout << "*(unsigned short*)&data[18] -> 2 bytes "
<< std::bitset<32>(*(unsigned short*)&data[18]) << std::endl;
std::cout << "*(int*)&data[18] -> 4 bytes "
<< std::bitset<32>(*(int*)&data[18]) << std::endl;
}
Run Code Online (Sandbox Code Playgroud)
data[18] -> 1 byte 00000000000000000000000010011010
*(unsigned short*)&data[18] -> 2 bytes 00000000000000001001101010011010
*(int*)&data[18] -> 4 bytes 10011010100110101001101010011010
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
271 次 |
| 最近记录: |