我尝试使用此方法加载BMP图像:
int TextureManager::LoadBMP(std::string path, unsigned int &texture)
{
unsigned char* datBuff[2] = { nullptr, nullptr }; // Header buffers
unsigned char* pixels = nullptr; // Pixels
BITMAPFILEHEADER* bmpHeader = nullptr; // Header
BITMAPINFOHEADER* bmpInfo = nullptr; // Info
std::ifstream file(path, std::ios::binary);
if (!file)
{
std::cout << "Failure to open bitmap file.\n";
return 1;
}
// Allocate byte memory that will hold the two headers
datBuff[0] = new unsigned char[sizeof(BITMAPFILEHEADER)];
datBuff[1] = new unsigned char[sizeof(BITMAPINFOHEADER)];
file.read((char*)datBuff[0], sizeof(BITMAPFILEHEADER));
file.read((char*)datBuff[1], sizeof(BITMAPINFOHEADER));
// Construct the values from the buffers
bmpHeader = (BITMAPFILEHEADER*)datBuff[0];
bmpInfo = (BITMAPINFOHEADER*)datBuff[1];
// Check if the file is an actual BMP file
if (bmpHeader->bfType != 0x4D42)
{
std::cout << "File \"" << path << "\" isn't a bitmap file\n";
return 2;
}
// First allocate pixel memory
pixels = new unsigned char[bmpInfo->biSizeImage];
// Go to where image data starts, then read in image data
file.seekg(bmpHeader->bfOffBits);
file.read((char*)pixels, bmpInfo->biSizeImage);
unsigned char tmpRGB = 0; // Swap buffer
for (unsigned long i = 0; i < bmpInfo->biSizeImage; i += 3)
{
tmpRGB = pixels[i];
pixels[i] = pixels[i + 2];
pixels[i + 2] = tmpRGB;
}
// Set width and height to the values loaded from the file
unsigned int w = bmpInfo->biWidth;
unsigned int h = bmpInfo->biHeight;
/TODO:***************GENERATING TEXTURES*******************/
// Output a successful message
std::cout << "Texture \"" << path << "\" successfully loaded.\n";
// Delete the two buffers.
delete[] datBuff[0];
delete[] datBuff[1];
delete[] pixels;
return 0; // Return success code
}
但是bmpInfo->biSizeImage
总是= 0,所以我搜索并发现我可以通过将宽度乘以高度(bpp / 8)来找出位图数据的字节大小,所以我编辑了功能是这样的:
int TextureManager::LoadBMP(std::string path, unsigned int &texture)
{
unsigned char* datBuff[2] = { nullptr, nullptr }; // Header buffers
unsigned char* pixels = nullptr; // Pixels
BITMAPFILEHEADER* bmpHeader = nullptr; // Header
BITMAPINFOHEADER* bmpInfo = nullptr; // Info
std::ifstream file(path, std::ios::binary);
if (!file)
{
std::cout << "Failure to open bitmap file.\n";
return 1;
}
// Allocate byte memory that will hold the two headers
datBuff[0] = new unsigned char[sizeof(BITMAPFILEHEADER)];
datBuff[1] = new unsigned char[sizeof(BITMAPINFOHEADER)];
file.read((char*)datBuff[0], sizeof(BITMAPFILEHEADER));
file.read((char*)datBuff[1], sizeof(BITMAPINFOHEADER));
// Construct the values from the buffers
bmpHeader = (BITMAPFILEHEADER*)datBuff[0];
bmpInfo = (BITMAPINFOHEADER*)datBuff[1];
// Check if the file is an actual BMP file
if (bmpHeader->bfType != 0x4D42)
{
std::cout << "File \"" << path << "\" isn't a bitmap file\n";
return 2;
}
DWORD FileDataSize;
DWORD ActualDataSize;
LONG AjustedWidth;
LONG WidthOver = 0;
if (((bmpInfo->biWidth * (bmpInfo->biBitCount / 8)) % 4) != 0)
{
WidthOver = 4 - ((bmpInfo->biWidth * (bmpInfo->biBitCount / 8)) % 4);
}
AjustedWidth = bmpInfo->biWidth + WidthOver;
ActualDataSize = bmpInfo->biWidth * bmpInfo->biHeight * (bmpInfo->biBitCount / 8);
FileDataSize = AjustedWidth * bmpInfo->biHeight * (bmpInfo->biBitCount / 8);
// First allocate pixel memory
pixels = new unsigned char[FileDataSize];
// Go to where image data starts, then read in image data
file.seekg(bmpHeader->bfOffBits);
file.read((char*)pixels, FileDataSize);
unsigned char tmpRGB = 0; // Swap buffer
for (unsigned long i = 0; i < FileDataSize; i += 3)
{
tmpRGB = pixels[i];
pixels[i] = pixels[i + 2];
pixels[i + 2] = tmpRGB;
}
// Set width and height to the values loaded from the file
unsigned int w = bmpInfo->biWidth;
unsigned int h = bmpInfo->biHeight;
/TODO:***************GENERATING TEXTURES*******************/
// Output a successful message
std::cout << "Texture \"" << path << "\" successfully loaded.\n";
// Delete the two buffers.
delete[] datBuff[0];
delete[] datBuff[1];
delete[] pixels;
return 0; // Return success code
}
现在它没有读取像素,可变像素总是0,这里做错了什么?
编辑:bmpInfo
biSize 40
biWidth 1024
biHeight 1024
biPlanes 1
biBitCount 32
biCompression 0
biSizeImage 0
biXPelsPerMeter 0
biYPelsPerMeter 0
biClrUsed 0
biClrImportant 0
答案 0 :(得分:1)
根据我们的转换MixedCoder,我认为您尝试加载的位图未正确保存。我们可以看到
bmpHeader.bfOffBits = 54;
这意味着如果我们将标题的修复大小减去14。这为bmpInfo留下了40个字节,根据定义,它是BITMAPINFOHEADER的大小。所以我们可以排除一些错位问题。
我只是使用Paint再次保存该图像并以此方式加载。
答案 1 :(得分:1)
对于RGB位图,正确的biSizeImage条目可以保留为零。 Microsoft记录了行为here。在这种情况下,您必须使用biWidth和biHeight使用不同的计算。
因此,您正在测试的位图不一定存在缺陷,应为此案例准备一个通用的BMP阅读器。