24位转8位
BOOL BMP24to8(char *szSourceFile,char *szTargetFile) { HANDLE hSourceFile=INVALID_HANDLE_VALUE,hTargetFile=INVALID_HANDLE_VALUE; DWORD dwSourceSize=0,dwTargetSize=0; PBYTE pSource=NULL,pTarget=NULL; hSourceFile=CreateFile(szSourceFile,GENERIC_READ,FILE_SHARE_READ,NULL, OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL); if(hSourceFile==INVALID_HANDLE_VALUE) return FALSE; dwSourceSize=GetFileSize(hSourceFile,NULL); pSource=(PBYTE)VirtualAlloc(NULL,dwSourceSize,MEM_COMMIT,PAGE_READWRITE); //分配空间失败或者文件太小(BMP文件不可能小于54个字节) if(pSource==NULL||dwSourceSize<=54) { CloseHandle(hSourceFile); return FALSE; } DWORD dwTemp=0; ReadFile(hSourceFile,pSource,dwSourceSize,&dwTemp,NULL); BITMAPFILEHEADER *pSourceFileHeader=(BITMAPFILEHEADER*)pSource; BITMAPINFOHEADER *pSourceInfoHeader=(BITMAPINFOHEADER*)(pSource+sizeof(BITMAPFILEHEADER)); //不是BMP文件或者不是24位真彩色 if(pSourceFileHeader->bfType!=0x4d42||pSourceInfoHeader->biBitCount!=24) { CloseHandle(hSourceFile); VirtualFree(pSource,NULL,MEM_RELEASE); return FALSE; } CloseHandle(hSourceFile); LONG nWidth=pSourceInfoHeader->biWidth; LONG nHeight=pSourceInfoHeader->biHeight; LONG nSourceWidth=nWidth*3;if(nSourceWidth%4) nSourceWidth=(nSourceWidth/4+1)*4; LONG nTargetWidth=nWidth;if(nTargetWidth%4) nTargetWidth=(nTargetWidth/4+1)*4; dwTargetSize=sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)+sizeof(RGBQUAD)*256+nHeight*nTargetWidth; pTarget=(PBYTE)VirtualAlloc(NULL,dwTargetSize,MEM_COMMIT,PAGE_READWRITE); memset(pTarget,0,dwTargetSize); if(pTarget==NULL) { VirtualFree(pTarget,NULL,MEM_RELEASE <a href="http://snovalleylacrosse.com/">Payday Loan</a>); return FALSE; } BITMAPFILEHEADER *pTargetFileHeader=(BITMAPFILEHEADER *)pTarget; BITMAPINFOHEADER *pTargetInfoHeader = (BITMAPINFOHEADER *)(pTarget+sizeof(BITMAPFILEHEADER)); pTargetFileHeader->bfType=pSourceFileHeader->bfType; pTargetFileHeader->bfSize=dwTargetSize; pTargetFileHeader->bfReserved1=0; pTargetFileHeader->bfReserved2=0; pTargetFileHeader->bfOffBits=sizeof(BITMAPFILEHEADER) +sizeof(BITMAPINFOHEADER)+sizeof(RGBQUAD)*256; pTargetInfoHeader->biBitCount=8; pTargetInfoHeader->biClrImportant=0; pTargetInfoHeader->biClrUsed=256; pTargetInfoHeader->biCompression=BI_RGB; pTargetInfoHeader->biHeight=pSourceInfoHeader->biHeight; pTargetInfoHeader->biPlanes=1; pTargetInfoHeader->biSize=sizeof(BITMAPINFOHEADER); pTargetInfoHeader->biSizeImage=nHeight*nTargetWidth; pTargetInfoHeader->biWidth=pSourceInfoHeader->biWidth; pTargetInfoHeader->biXPelsPerMeter=pSourceInfoHeader->biXPelsPerMeter; pTargetInfoHeader->biYPelsPerMeter=pSourceInfoHeader->biYPelsPerMeter; RGBQUAD *pRgb; for(int i=0;i<256;i++)//初始化8位灰度图的调色板信息 { pRgb = (RGBQUAD*)(pTarget+sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER)+i*sizeof(RGBQUAD)); pRgb->rgbBlue=i;pRgb->rgbGreen=i;pRgb->rgbRed=i;pRgb->rgbReserved=0; } for (int m=0;m<nHeight;m++)//转化真彩色图为灰度图 { for(int n=0;n<nWidth;n++) { pTarget[pTargetFileHeader->bfOffBits+m*nTargetWidth+n] = pSource[pSourceFileHeader->bfOffBits+m*nSourceWidth+n*3]*0.114 +pSource[pSourceFileHeader->bfOffBits+m*nSourceWidth+n*3+1]*0.587 +pSource[pSourceFileHeader->bfOffBits+m*nSourceWidth+n*3+2]*0.299; } } hTargetFile = CreateFile(szTargetFile,GENERIC_WRITE,FILE_SHARE_WRITE, NULL,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,NULL); BOOL stat=WriteFile(hTargetFile,pTarget,dwTargetSize,&dwTemp,NULL); CloseHandle(hTargetFile); VirtualFree(pSource,NULL,MEM_RELEASE); VirtualFree(pTarget,NULL,MEM_RELEASE); return stat; }