【发布时间】:2018-03-11 02:02:59
【问题描述】:
首先,这不是重复的。我已经阅读了Converting 1-bit bmp file to array in C/C++,我的问题是关于我在提供给我的公式中看到的不一致。
问题
我正在尝试读取在 MS Paint 中创建的 1 位位图图像。我使用了本网站上其他答案提供的代码,但我必须更改一些内容才能使其正常工作,我想了解原因,
变化1:lineSize必须加倍
原创
int lineSize = (w / 8 + (w / 8) % 4);
我的:
int lineSize = (w/ 8 + (w / 8) % 4) * 2;
更改 2:必须颠倒字节顺序
原文:
for(k = 0 ; k < 8 ; k++)
... (data[fpos] >> k ) & 1;
我的:
for (int k = 7; k >= 0; --k) {
... (data[rawPos] >> k) & 1;
完整代码
注意:此代码有效。与原作有一些变化,但核心读取部分是一样的。
vector<vector<int>> getBlackAndWhiteBmp(string filename) {
BmpHeader head;
ifstream f(filename, ios::binary);
if (!f) {
throw "Invalid file given";
}
int headSize = sizeof(BmpHeader);
f.read((char*)&head, headSize);
if (head.bitsPerPixel != 1) {
f.close();
throw "Invalid bitmap loaded";
}
int height = head.height;
int width = head.width;
// Lines are aligned on a 4-byte boundary
int lineSize = (width / 8 + (width / 8) % 4) * 2;
int fileSize = lineSize * height;
vector<unsigned char> rawFile(fileSize);
vector<vector<int>> img(head.height, vector<int>(width, -1));
// Skip to where the actual image data is
f.seekg(head.offset);
// Read in all of the file
f.read((char*)&rawFile[0], fileSize);
// Decode the actual boolean values of the pixesl
int row;
int reverseRow; // Because bitmaps are stored bottom to top for some reason
int columnByte;
int columnBit;
for (row = 0, reverseRow = height - 1; row < height; ++row, --reverseRow) {
columnBit = 0;
for (columnByte = 0; columnByte < ceil((width / 8.0)); ++columnByte) {
int rawPos = (row * lineSize) + columnByte;
for (int k = 7; k >= 0 && columnBit < width; --k, ++columnBit) {
img[reverseRow][columnBit] = (rawFile[rawPos] >> k) & 1;
}
}
}
f.close();
return img;
}
#pragma pack(1)
struct BmpHeader {
char magic[2]; // 0-1
uint32_t fileSize; // 2-5
uint32_t reserved; // 6-9
uint32_t offset; // 10-13
uint32_t headerSize; // 14-17
uint32_t width; // 18-21
uint32_t height; // 22-25
uint16_t bitsPerPixel; // 26-27
uint16_t bitDepth; // 28-29
};
#pragma pack()
可能相关的信息:
- 我使用的是 Visual Studio 2017
- 我正在为 C++14 编译
- 我使用的是 Windows 10 操作系统
谢谢。
【问题讨论】: