我想使用 C++ 读写 BMP 图像,当我将我的类与 24 位图像一起使用时,但当我使用 8 位图像时不起作用(绘画无法打开文件),类似于 1位图。
我使用“打开”功能打开一个 bmp 文件,然后使用“保存”功能保存它(及其标题)(我只是复制它)。只有当文件是 24 位 bmp 文件时,结果文件才会打开。我不创建任何 header ,我使用 Open 函数从源复制 header
我使用的代码是(参见加载和保存函数):
#pragma pack(push, 1)
struct FILEHEADER
{
WORD bfType;
DWORD bfSize;
WORD bfReserved1;
WORD bfReserved2;
DWORD bOffBits;
};
#pragma pack(pop)
#pragma pack(push, 1)
struct INFOHEADER
{
DWORD biSize;
LONG biWidth;
LONG biHeight;
WORD biPlanes;
WORD biBitCount;
DWORD biCompression;
DWORD biSizeImage;
LONG biXPelsPerMeter;
LONG biYPelsPerMeter;
DWORD biClrUsed;
DWORD biClrImportant;
};
typedef INFOHEADER infoheader;
typedef FILEHEADER fileheader;
const WORD BMP_FORMAT = 0x4D42;
class Bitmap2
{
private:
BYTE *data;
infoheader h_info;
fileheader h_file;
WORD Type();
DWORD OffBits();
DWORD ImageSize();
LONG Rows();
LONG Cols();
WORD BitsPerPixel();
DWORD SizeInBytes();
public:
void Load(char *filename);
void Save(char *filename);
void PrintHeaders();
};
void Bitmap2::Load(char *filename)
{
std::ifstream file;
file.open(filename, std::fstream::binary);
if (!file.is_open())
return;
file.read((char *)&(h_file), sizeof(fileheader));
//
if (Type() != BMP_FORMAT)
{
file.close();
return;
}
file.read((char *)&h_info, sizeof(infoheader));
//
file.seekg(OffBits());
data = new BYTE[SizeInBytes()];
if (!data)
{
delete data;
file.close();
return;
}
file.read((char *)data, SizeInBytes());
if (data == NULL)
{
file.close();
return;
}
file.close();
}
void Bitmap2::Save(char *filename)
{
std::ofstream file;
if (!data)
return;
file.open(filename, std::fstream::binary);
if (!file.is_open())
return;
file.write((char *)&(h_file), sizeof(fileheader));
//
if (Type() != BMP_FORMAT)
{
file.close();
return;
}
file.write((char *)&h_info, sizeof(infoheader));
file.write((char *)data, SizeInBytes());
file.close();
}
void Bitmap2::PrintHeaders()
{
std::cout << "biSize = " << h_info.biSize << std::endl;
std::cout << "biWidth = " << h_info.biWidth << std::endl;
std::cout << "biHeight = " << h_info.biHeight << std::endl;
std::cout << "biPlanes = " << h_info.biPlanes << std::endl;
std::cout << "biBitCount = " << h_info.biBitCount << std::endl;
std::cout << "biCompression = " << h_info.biCompression << std::endl;
std::cout << "biSizeImage = " << h_info.biSizeImage << std::endl;
std::cout << "biXPelsPerMeter = " << h_info.biXPelsPerMeter << std::endl;
std::cout << "biYPelsPerMeter = " << h_info.biYPelsPerMeter << std::endl;
std::cout << "biClrUsed = " << h_info.biClrUsed << std::endl;
std::cout << "biClrImportant = " << h_info.biClrImportant << std::endl;
}
WORD Bitmap2::Type()
{
return h_file.bfType;
}
DWORD Bitmap2::OffBits()
{
return h_file.bOffBits;
}
DWORD Bitmap2::ImageSize()
{
return h_info.biSizeImage;
}
LONG Bitmap2::Rows()
{
return h_info.biHeight;
}
LONG Bitmap2::Cols()
{
return h_info.biWidth;
}
WORD Bitmap2::BitsPerPixel()
{
return h_info.biBitCount;
}
DWORD Bitmap2::SizeInBytes()
{
return h_info.biSizeImage;
}
int main()
{
Bitmap2 x;
x.Load("test.bmp");
x.Save("test_o.bmp");
x.PrintHeaders();
std::cout << "__________" << std::endl;
}
最佳答案
biSizeImage
may be 0 ,在这种情况下,您必须计算实际大小。
此外,我看不到您在哪里读写 color table (调色板)。由于 1 位和 8 位位图文件需要调色板,而 24 位位图文件不需要,我怀疑这是您的根本问题。
关于c++ - 使用 C++ 读取 1、8 或 24 位 BMP 文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40624303/