把一个真彩图test.bmp转化为一个256阶灰度图1.bmp 执行过程没有报错 可1.bmp 打开不是一个正确的图片 大家帮我看看 谢谢
把一个真彩图test.bmp转化为一个256阶灰度图1.bmp 执行过程没有报错 可1.bmp 打开不是一个正确的图片 大家帮我看看 谢谢
#include "stdafx.h"
#include "stdio.h"
#include "windows.h"
typedef struct tagLongPointer
{
LPVOID lpImgData;
LONG biWidth;
LONG biHeight;
}LongPointer;
#define WIDTHBYTES(i) ((i+31)/32*4)
bool LoadGrayBmpFile (char *BmpFileName);
HGLOBAL hImgData=NULL;
LongPointer lpimg;
LPVOID lpgimg1;
LPVOID lpgimg2;
int main(int argc, char* argv[])
{
if (LoadGrayBmpFile("C:\\test.bmp") )
{
printf("OK!\n");
}
GlobalUnlock(hImgData);
return 0;
}
bool LoadGrayBmpFile (char *BmpFileName)
{
HANDLE hf,hpal,ghf,ghf1;
LPSTR lpg1,lpg2;
LPVOID lpPal,lpImgData;
LPSTR pal;
DWORD LineBytes,gLineBytes;
DWORD ImgSize,Gsize;
DWORD NumColors;
DWORD i;
unsigned char r,g,b;
float gy;
BITMAPFILEHEADER bf,gbf;
BITMAPINFOHEADER bi,gbi;
lpimg.lpImgData = NULL ;
lpimg.biWidth = 0 ;
lpimg.biHeight = 0 ;
hf=CreateFile(BmpFileName,GENERIC_READ,FILE_SHARE_READ,NULL,
OPEN_EXISTING,FILE_ATTRIBUTE_READONLY,NULL);
ReadFile(hf,&bf,sizeof(BITMAPFILEHEADER),&i,NULL);
ReadFile(hf,&bi,sizeof(BITMAPINFOHEADER),&i,NULL);
gbf=bf;
gbi=bi;
LineBytes=(DWORD)WIDTHBYTES(bi.biWidth*bi.biBitCount);
gLineBytes=(DWORD)WIDTHBYTES(bi.biWidth*8);
ImgSize=(DWORD)LineBytes*bi.biHeight;
Gsize=(DWORD)gLineBytes*bi.biHeight;
gbf.bfOffBits=(DWORD)(256*sizeof(RGBQUAD)+sizeof(BITMAPFILEHEADER)
+sizeof(BITMAPINFOHEADER));
gbf.bfSize=(DWORD)(256*sizeof(RGBQUAD)+sizeof(BITMAPFILEHEADER)
+sizeof(BITMAPINFOHEADER)+Gsize);
gbi.biBitCount=8;
gbi.biClrUsed=0;
gbi.biSizeImage=Gsize;
if(bi.biClrUsed!=0)
NumColors=(DWORD)bi.biClrUsed;
else
switch(bi.biBitCount){
case 1:
NumColors=2;
break;
case 4:
NumColors=16;
break;
case 8:
NumColors=256;
break;
case 24:
NumColors=0;
break;
default:
MessageBox(0,"Invalid color numbers!","Error Message",MB_OK|MB_ICONEXCLAMATION);
CloseHandle(hf);
return FALSE;
}
if(bi.biClrUsed!=0)
{
MessageBox(0,"The file is not a true color!","Error Message" ,MB_OK|MB_ICONEXCLAMATION);
CloseHandle(hf);
return FALSE;
}
if(bf.bfOffBits!=(DWORD)(NumColors*sizeof(RGBQUAD)+sizeof(BITMAPFILEHEADER)
+sizeof(BITMAPINFOHEADER)))
{
MessageBox(0,"Invalid color numbers!","Error Message" ,MB_OK|MB_ICONEXCLAMATION);
CloseHandle(hf);
return FALSE;
}
bf.bfSize=sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)+NumColors*sizeof(RGBQUAD)+ImgSize;
hImgData=GlobalAlloc(GPTR,(DWORD)(ImgSize+1000));
lpImgData=GlobalLock(hImgData);
hpal=GlobalAlloc(GPTR,(DWORD)(256*4));
lpPal=GlobalLock(hpal);
pal=(char *)lpPal;
for(int z=0;z<256;z++)
{
*(pal++)=(unsigned char)z;
*(pal++)=(unsigned char)z;
*(pal++)=(unsigned char)z;
*(pal++)=0;
}
ghf1=GlobalAlloc(GPTR,(DWORD)(Gsize+1000));
lpgimg1=GlobalLock(ghf1);
lpimg.lpImgData = lpImgData ;
lpimg.biHeight = bi.biHeight ;
lpimg.biWidth = bi.biWidth ;
SetFilePointer(hf,bf.bfOffBits,NULL,FILE_BEGIN);
ReadFile(hf,lpImgData,ImgSize,&i,NULL);
for(int y=0;y<lpimg.biHeight;y++)
{
lpg1=(char *)lpImgData+ImgSize-y*LineBytes;
lpg2=(char *)lpgimg1+Gsize-y*gLineBytes;
for(int x=0;x<lpimg.biWidth;x++)
{
b=(unsigned char)(*lpg1++);
g=(unsigned char)(*lpg1++);
r=(unsigned char)(*lpg1++);
gy=(float)(b*0.299+g*0.587+b*0.114);
*(lpg2++)=(unsigned char)gy;
}
}
lpgimg2=lpgimg1;
ghf=CreateFile("C:\\1.bmp",GENERIC_WRITE,FILE_SHARE_WRITE,NULL,
CREATE_NEW,FILE_ATTRIBUTE_ARCHIVE,NULL);
WriteFile(ghf,(char *)&gbi,sizeof(BITMAPFILEHEADER),&i,NULL);
WriteFile(ghf,(char *)&gbf,sizeof(BITMAPINFOHEADER),&i,NULL);
WriteFile(ghf,(char *)lpPal,256*4,&i,NULL);
WriteFile(ghf,(char *)lpgimg1,Gsize,&i,NULL);
CloseHandle(hf);
CloseHandle(ghf);
return TRUE;
}