首页
社区
课程
招聘
[求助]saveBitmap()是截屏的,但不知为什么位图颜色不对
发表于: 2009-1-16 17:24 8040

[求助]saveBitmap()是截屏的,但不知为什么位图颜色不对

2009-1-16 17:24
8040
void saveBitmap()
{
HDC hdc=GetDC(NULL);
int wScreen=GetSystemMetrics(SM_CXSCREEN);
int hScreen=GetSystemMetrics(SM_CYSCREEN);
HDC memdc=CreateCompatibleDC(hdc);
HBITMAP hBitmap=CreateCompatibleBitmap(hdc,wScreen,hScreen);
SelectObject(memdc,hBitmap);
BitBlt(memdc,0,0,wScreen,hScreen,hdc,0,0,SRCCOPY);
BITMAPINFO bi;
//RtlZeroMemory(&bi,sizeof(bi));
bi.bmiHeader.biSize=sizeof(bi.bmiHeader);
bi.bmiHeader.biWidth=wScreen;
bi.bmiHeader.biHeight=hScreen;
bi.bmiHeader.biPlanes=1;
bi.bmiHeader.biBitCount=24;
bi.bmiHeader.biCompression=BI_RGB;
bi.bmiHeader.biSizeImage=0;
bi.bmiHeader.biXPelsPerMeter=wScreen;
bi.bmiHeader.biYPelsPerMeter=hScreen;
bi.bmiHeader.biClrUsed=0;
bi.bmiHeader.biClrImportant=0;

    int bitsize=wScreen*hScreen*3;
BYTE* buff=new BYTE[bitsize];
    RtlZeroMemory(buff,bitsize);
GetDIBits(memdc,hBitmap,0,hScreen,buff,&bi,DIB_RGB_COLORS);
BITMAPFILEHEADER bf;
bf.bfType=0x4d42;
bf.bfSize=bitsize+14+sizeof(BITMAPINFOHEADER);
bf.bfOffBits=sizeof(bi.bmiHeader)+sizeof(bf);
bf.bfReserved1=0;
bf.bfReserved2=0;
HANDLE hFile=CreateFile(L"桌面 .bmp",GENERIC_WRITE,FILE_SHARE_READ,NULL,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,NULL);
DWORD num=0;
WriteFile(hFile,&bf,sizeof(bf),&num,NULL);
WriteFile(hFile,&bi,sizeof(bi),&num,NULL);
WriteFile(hFile,buff,bitsize,&num,NULL);
CloseHandle(hFile);

delete buff;
}
这个函数是截屏然后保存为一副位图,但是不知道为什么位图的颜色不正确,请教各位大侠。我自己已经查了3天了,始终不知道错在哪,MSDN我也看过,都要崩溃了。

[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!

收藏
免费 0
支持
分享
最新回复 (9)
雪    币: 201
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
刚才发的着急,标题忘写了
2009-1-16 17:26
0
雪    币: 2384
活跃值: (766)
能力值: (RANK:410 )
在线值:
发帖
回帖
粉丝
3
bi.bmiHeader.biBitCount=24;改成16就可以了。
2009-1-16 22:34
0
雪    币: 201
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
感谢楼上的,此问题我查了N天,如果不介意,请告诉我原因,不过忙就不麻烦了,我自己查资料去。不过24这个参数也是我从别的代码那里看来的,为什么我用24就不行呢?
2009-1-19 17:25
0
雪    币: 2384
活跃值: (766)
能力值: (RANK:410 )
在线值:
发帖
回帖
粉丝
5
原因我也未明,我只是测试了你的代码参数得到结果而已。我估计着原因可能是由调色板所造成的。
2009-1-19 19:26
0
雪    币: 202
活跃值: (11)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
我用的也是24是可以的.
2009-1-20 09:17
0
雪    币: 201
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
7
我看过好几个正确代码,都是用的24,所以当初我没想到会是24这个参数的问题,5楼的,请问你是怎么测试的,逆向吗???能否指点下,谢谢了。。。。。
2009-1-22 13:35
0
雪    币: 201
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
8
5楼的大侠,其实比起这问题的原因, 更想知道您是如何测试的,我参考别人代码的时候经常出现问题,别人的代码好使,而我用就不行,我诚心的请教您是怎么测试的,我是新手,一般有问题只能GOOGLE或者来论坛了,如果能自己测试出来,感觉更加实用。
2009-1-22 14:02
0
雪    币: 2384
活跃值: (766)
能力值: (RANK:410 )
在线值:
发帖
回帖
粉丝
9
一般调用API函数的问题我都是查看msdn的参数对照程序有没有调用错误。然后根据msdn上的各类参数都试一下,再运行程序看看结果,或者用调试器调试一下参数有没有传输正确等方法来测试。比如你这个问题,原因我已经知道了,是因为你调用的GetDIBits函数的最后一个参数用错了。你的最后一个参数是DIB_RGB_COLORS,而我查找过MSDN,从MSDN上看到这么一句话。
BITMAPINFO
The BITMAPINFO structure defines the dimensions and color information for a DIB.

typedef struct tagBITMAPINFO {
  BITMAPINFOHEADER bmiHeader;
  RGBQUAD          bmiColors[1];
} BITMAPINFO, *PBITMAPINFO;
Members
bmiHeader
Specifies a BITMAPINFOHEADER structure that contains information about the dimensions of color format.
.

bmiColors
The bmiColors member contains one of the following:
An array of RGBQUAD. The elements of the array that make up the color table.
An array of 16-bit unsigned integers that specifies indexes into the currently realized logical palette. This use of bmiColors is allowed for functions that use DIBs. When bmiColors elements contain indexes to a realized logical palette, they must also call the following bitmap functions:
CreateDIBitmap

CreateDIBPatternBrush

CreateDIBSection

The iUsage parameter of CreateDIBSection must be set to DIB_PAL_COLORS.

The number of entries in the array depends on the values of the biBitCount and biClrUsed members of the BITMAPINFOHEADER structure.

The colors in the bmiColors table appear in order of importance. For more information, see the Remarks section.

所以我就在想,用GetDIBits的参数是不是也是应该用DIB_PAL_COLORS参数,经过测试程序可以通过测试用24也没问题了。
2009-1-22 14:11
0
雪    币: 201
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
10
感谢楼上的大侠,不过我刚才也查了很久MSDN,下面是16和24的说明:
16 The bitmap has a maximum of 2^16 colors. If the biCompression member of the BITMAPINFOHEADER is BI_RGB, the bmiColors member of BITMAPINFO is NULL. Each WORD in the bitmap array represents a single pixel. The relative intensities of red, green, and blue are represented with five bits for each color component. The value for blue is in the least significant five bits, followed by five bits each for green and red. The most significant bit is not used. The bmiColors color table is used for optimizing colors used on palette-based devices, and must contain the number of entries specified by the biClrUsed member of the BITMAPINFOHEADER.
If the biCompression member of the BITMAPINFOHEADER is BI_BITFIELDS, the bmiColors member contains three DWORD color masks that specify the red, green, and blue components, respectively, of each pixel. Each WORD in the bitmap array represents a single pixel.

Windows NT/Windows 2000/XP: When the biCompression member is BI_BITFIELDS, bits set in each DWORD mask must be contiguous and should not overlap the bits of another mask. All the bits in the pixel do not have to be used.

Windows 95/98/Me: When the biCompression member is BI_BITFIELDS, the system supports only the following 16bpp color masks: A 5-5-5 16-bit image, where the blue mask is 0x001F, the green mask is 0x03E0, and the red mask is 0x7C00; and a 5-6-5 16-bit image, where the blue mask is 0x001F, the green mask is 0x07E0, and the red mask is 0xF800.

24 The bitmap has a maximum of 2^24 colors, and the bmiColors member of BITMAPINFO is NULL. Each 3-byte triplet in the bitmap array represents the relative intensities of blue, green, and red, respectively, for a pixel. The bmiColors color table is used for optimizing colors used on palette-based devices, and must contain the number of entries specified by the biClrUsed member of the BITMAPINFOHEADER.  
我发现我代码错是因为如果设置为24,the bmiColors member of BITMAPINFO is NULL,可能是应该没有bmiColors部分,而我的代码WriteFile(hFile,&bi,sizeof(bi),&num,NULL);
恰恰写入了bmiColors部分,所以可能造成了后面数据的错位,而改为16后,就需要有bmiColors部分,所以颜色数据就正常了,而把WriteFile(hFile,&bi,sizeof(bi),&num,NULL)中的写入数据大小改为sizeof(BITMAPINFOHEADER),用24为参数,则图片颜色同样正常。但是我之前几天迷茫的时候就试过使用DIB_PAL_COLORS参数,颜色也不对,可能我改的有些着急吧。不过很感谢小虾大侠的帮忙,很感动,能在快过年的情况下帮我看代码,辛苦了,祝您新年快乐。由于我一直都是一个人弄代码,所以出错时候感觉就像在迷宫里乱走,也许是很简单的问题都会浪费很长时间,希望高手别见笑,请多多指教。
2009-1-22 15:21
0
游客
登录 | 注册 方可回帖
返回
//