把一个真彩图test.bmp转化为一个256阶灰度图1.bmp 执行过程没有报错 可1.bmp 打开不是一个正确的图片 大家帮我看看 谢谢

hacking 2003-01-16 10:27:10
把一个真彩图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;
}
...全文
21 3 打赏 收藏 举报
写回复
3 条回复
切换为时间正序
当前发帖距今超过3年,不再开放新的回复
发表回复
San_Daniel 2003-01-17
找一个宽度为4的倍数的图来试试
  • 打赏
  • 举报
回复
seanzh 2003-01-17
灰度图就是说RGB值是一样的图,你按这个原理来转换就行了
具体的转换过程不难
  • 打赏
  • 举报
回复
kvk 2003-01-16
ghf=CreateFile("1.bmp",GENERIC_WRITE,FILE_SHARE_WRITE,NULL,
CREATE_NEW,FILE_ATTRIBUTE_ARCHIVE,NULL);
WriteFile(ghf,(char *)&gbf,sizeof(BITMAPFILEHEADER),&i,NULL);
WriteFile(ghf,(char *)&gbi,sizeof(BITMAPINFOHEADER),&i,NULL);

WriteFile(ghf,(char *)lpPal,256*4,&i,NULL);
WriteFile(ghf,(char *)lpgimg1,Gsize,&i,NULL);
顺序问题
  • 打赏
  • 举报
回复
相关推荐
发帖
工具平台和程序库

2.4w+

社区成员

C/C++ 工具平台和程序库
社区管理员
  • 工具平台和程序库社区
加入社区
帖子事件
创建了帖子
2003-01-16 10:27
社区公告
暂无公告