位图文件结构很好分析,不像png图像。
//处理位图
//@szPath: 位图的路径
VOID HandleBitmap(CHAR* szPath)
{
//路径不为空 字符串地址不为空
if (!strlen(szPath) || !szPath)
return;
//判断是否是位图文件
INT nPathLen = strlen(szPath);
_strupr(szPath);
if (strncmp(&szPath[nPathLen - 4], ".BMP", 4))
return;
HANDLE hFile = 0; //位图的句柄
INT nFileSize; //位图的总大小
LPBYTE pBuffer = 0; //整个位图的缓冲区
DWORD dwByte; //读取数据的大小
BITMAPFILEHEADER stFile; //位图文件头
BITMAPINFOHEADER stInfo; //位图信息头
LPBYTE pData; //位图RGB数据
LPBYTE pDataRGB[3] = { 0 }; //只带一个颜色的RGB数据
BOOL bTip; //辅助标志
INT nLineLen; //位图一行RGB数据的大小
INT nBit; //颜色位
HANDLE hWrite = 0; //写入的文件句柄
CHAR szNewPath[MAX_PATH]; //新位图路径
do
{
//打开位图
hFile = CreateFileA(szPath, GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, 0, 0);
if (!hFile)
break;
//获取位图大小
nFileSize = GetFileSize(hFile, 0);
if(!nFileSize)
break;
//申请空间
pBuffer = (LPBYTE)VirtualAlloc(0, nFileSize, MEM_COMMIT, PAGE_READWRITE);
if(!pBuffer)
break;
//读取位图数据
ReadFile(hFile, pBuffer, nFileSize, &dwByte, 0);
if(!dwByte)
break;
//关闭位图句柄
CloseHandle(hFile);
hFile = 0;
//复制位图文件头 位图信息头 和位图RGB数据
CopyMemory(&stFile, pBuffer, sizeof(BITMAPFILEHEADER));
CopyMemory(&stInfo, (pBuffer + sizeof(BITMAPFILEHEADER)), sizeof(BITMAPINFOHEADER));
pData = (pBuffer + sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER));
if (stInfo.biBitCount != 24)
break;
//申请内存
bTip = FALSE;
for (int nIndex = 0; nIndex < 3; nIndex++)
{
pDataRGB[nIndex] = (LPBYTE)VirtualAlloc(0, nFileSize - sizeof(BITMAPFILEHEADER) - sizeof(BITMAPINFOHEADER), MEM_COMMIT, PAGE_READWRITE);
if (!pDataRGB[nIndex])
{
bTip = TRUE;
break;
}
}
//判断申请是否失败
if(bTip)
break;
//获取位图一行颜色的长度和颜色位
nLineLen = (stInfo.biWidth*stInfo.biBitCount / 8 + 3) / 4 * 4;
nBit = stInfo.biBitCount / 8;
//提取指定RGB颜色到指定内存
for (int nHeight = 0; nHeight < stInfo.biHeight; nHeight++)
{
for (int nWidth = 0; nWidth < stInfo.biWidth; nWidth++)
{
for (int nRGB = 0; nRGB < nBit; nRGB++)
{
pDataRGB[nRGB][nLineLen*nHeight + nWidth * nBit + nRGB] = pData[nLineLen*nHeight + nWidth * nBit + nRGB];
}
}
}
//分别写入到位图文件
for (int nIndex = 0; nIndex < 3; nIndex++)
{
//拼装新的位图文件头
wsprintf(szNewPath,"%s_%d_%s",szPath,nIndex,".BMP");
//创建新的单色位图文件
hWrite = CreateFileA(szNewPath, GENERIC_WRITE, FILE_SHARE_WRITE, 0, OPEN_ALWAYS, 0, 0);
if (!hWrite)
break;
//写入位图文件头
WriteFile(hWrite, &stFile, sizeof(BITMAPFILEHEADER), &dwByte, 0);
if(!dwByte)
break;
//写入位图信息头
WriteFile(hWrite, &stInfo, sizeof(BITMAPINFOHEADER), &dwByte, 0);
if(!dwByte)
break;
//写入单色位图数据
WriteFile(hWrite, pDataRGB[nIndex], nFileSize - sizeof(BITMAPFILEHEADER) - sizeof(BITMAPINFOHEADER), &dwByte, 0);
if(!dwByte)
break;
//关闭文件句柄
CloseHandle(hWrite);
hWrite = 0;
}
} while (0);
//释放。。。
if (hFile)
CloseHandle(hFile);
if (pBuffer)
VirtualFree(pBuffer, 0, MEM_RELEASE);
for (int nIndex = 0; nIndex < 3; nIndex++)
if (pDataRGB[nIndex])
VirtualFree(pDataRGB[nIndex], 0, MEM_RELEASE);
if (hWrite)
CloseHandle(hWrite);
}