64,644
社区成员
发帖
与我相关
我的任务
分享
// pdat是RGBA格式,w图像的宽,h高
void Bmp2RGBA(char* caFileName, DWORD** pdat, int& w, int& h)
{
FILE* pf = fopen(caFileName, "rb");
if (pf == NULL)
return;
BITMAPFILEHEADER bm;
fread(&bm, 1, sizeof(BITMAPFILEHEADER), pf);
if (bm.bfType!=*(WORD*)"BM")
{
fclose(pf);
return;
}
BITMAPINFOHEADER bmif;
fread(&bmif, 1, sizeof(BITMAPINFOHEADER), pf);
int bmx = bmif.biWidth;
int bmy = bmif.biHeight>0?bmif.biHeight:(-bmif.biHeight);
if (bmif.biBitCount < 8 || bmif.biCompression != 0)
{
fclose(pf);
return;
}
RGBQUAD *pRgb = NULL;
if (bmif.biBitCount == 8) // 256色bmp
{
pRgb = (RGBQUAD*) new BYTE[bmif.biClrUsed * sizeof(RGBQUAD)];
fread(pRgb, bmif.biClrUsed * sizeof(RGBQUAD), 1, pf);
}
BOOL bAlpha = FALSE;
if (bmif.biBitCount == 32) bAlpha = TRUE;// 带Alpha通道
DWORD dwRealWidth = (((bmx*bmif.biBitCount)+31)>>5)<<2;
int iBitSteps = bmif.biBitCount>>3;
DWORD iSize = dwRealWidth*bmy;
BYTE* pBmpData = NULL;
int readlines = bmy;
int readszie = iSize;
int readtimes = bmy/readlines;
if (iSize > 128*1024*1024)
{
readlines = (128*1024*1024/dwRealWidth);
readszie = readlines*dwRealWidth;
readtimes = bmy/readlines + 1;
}
pBmpData = new BYTE[readszie];
fseek(pf, bm.bfOffBits, SEEK_SET);
fread(pBmpData, 1, readszie, pf);
w = bmx;
h = bmy;
*pdat = new DWORD[w * h];
int iy,ix;
BYTE btPil;
char caTmp[4];
DWORD dwDataOff = 0;
int picy = 0;
for(int n = 0; n < readtimes; ++n)
{
for (iy = 0; iy < readlines; ++iy)
{
for (ix = 0; ix < bmx; ++ix)
{
if (pRgb == NULL)
{
caTmp[0] = pBmpData[(iy * dwRealWidth + ix * iBitSteps) + 2];
caTmp[1] = pBmpData[(iy * dwRealWidth + ix * iBitSteps) + 1];
caTmp[2] = pBmpData[(iy * dwRealWidth + ix * iBitSteps)];
}
else
{
btPil = pBmpData[(iy * dwRealWidth + ix * iBitSteps)];
if (bmif.biClrUsed != 0)
{
caTmp[0] = pRgb[btPil].rgbRed;
caTmp[1] = pRgb[btPil].rgbGreen;
caTmp[2] = pRgb[btPil].rgbBlue;
}
else
{
caTmp[0] = caTmp[1] = caTmp[2] = btPil;
}
}
if (bmif.biHeight < 0) // 有时bmp图像的高会是负值,这时则不用颠倒
{
dwDataOff = (iy + picy) * bmx + ix;
}
else
{
dwDataOff = (bmy - (iy + picy) - 1) * bmx + ix;
}
caTmp[3] = 255;
if (bAlpha)
{
caTmp[3] = pBmpData[(iy * dwRealWidth + ix * iBitSteps) + 3];
}
*pdat[dwDataOff] = *(DWORD*)caTmp;
}
}
picy += readlines;
int realbits = fread(pBmpData, 1, readszie, pf);
if (realbits < readszie) readlines = realbits / dwRealWidth;
}
if (pf)
fclose(pf);
pf = NULL;
}