我用的VC2010,思路就是先printwindow后台截图,然后用GetDIBits获得HBITMAP中的像素信息,再获取相应的RGB分量来进行操作,现在printdows没有问题,也可以正常的在粘贴板中显示截图,就是这个RGB的信息老不对,不知道下面的代码哪里有差错,24位,32位BMP都尝试过,但是不对,请高手帮忙看看,是哪里错了,或者还有更好的方法来获得HBITMAP中的像素信息
//==========================printwindow取色,这里没有问题===============
HWND temp=(HWND)0x3D08C6;
HDC hscrdc = ::GetDC(NULL);
RECT rc;
::GetClientRect(temp,&rc);
HBITMAP hbitmap = CreateCompatibleBitmap(hscrdc, rc.right - rc.left, rc.bottom - rc.top);
HDC hmemdc = CreateCompatibleDC(hscrdc);
SelectObject(hmemdc, hbitmap);
::PrintWindow(temp,hmemdc,PW_CLIENTONLY);
//================================定义BMP头文件信息,
BITMAPINFO bmpInf;
bmpInf.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
bmpInf.bmiHeader.biWidth = rc.right - rc.left;
bmpInf.bmiHeader.biHeight = rc.bottom - rc.top;
bmpInf.bmiHeader.biPlanes = 1;
bmpInf.bmiHeader.biBitCount = 24;
bmpInf.bmiHeader.biCompression = BI_RGB;
bmpInf.bmiHeader.biSizeImage = 0;
bmpInf.bmiHeader.biXPelsPerMeter=0;
bmpInf.bmiHeader.biYPelsPerMeter=0;
bmpInf.bmiHeader.biClrUsed=0;
bmpInf.bmiHeader.biClrImportant=0;
//---------------------这里的公式都是套用网上来的,---------------- BYTE *ptemp=new BYTE[((bmpInf.bmiHeader.biWidth*bmpInf.bmiHeader.biBitCount+31)/8)*bmpInf.bmiHeader.biHeight;
int Off;
int pitch=bmpInf.bmiHeader.biWidth%4;
int x=10;
int y=711;
Off=(y*bmpInf.bmiHeader.biWidth+x)*3+y*pitch; GetDIBits(hmemdc,hbitmap,0,(UINT)(bmpInf.bmiHeader.biHeight),ptemp,&bmpInf,DIB_RGB_COLORS);
BYTE B=ptemp[Off];
BYTE g=ptemp[Off+1];
BYTE r=ptemp[Off+2];
//==============这段是把BMP读到粘贴板的,也没有错误,显示的挺好...===========
::OpenClipboard(NULL);
EmptyClipboard();
SetClipboardData(CF_BITMAP, hbitmap);
CloseClipboard(); DeleteDC(hmemdc);
DeleteObject(hbitmap);
::ReleaseDC(NULL, hscrdc);
//==========================printwindow取色,这里没有问题===============
HWND temp=(HWND)0x3D08C6;
HDC hscrdc = ::GetDC(NULL);
RECT rc;
::GetClientRect(temp,&rc);
HBITMAP hbitmap = CreateCompatibleBitmap(hscrdc, rc.right - rc.left, rc.bottom - rc.top);
HDC hmemdc = CreateCompatibleDC(hscrdc);
SelectObject(hmemdc, hbitmap);
::PrintWindow(temp,hmemdc,PW_CLIENTONLY);
//================================定义BMP头文件信息,
BITMAPINFO bmpInf;
bmpInf.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
bmpInf.bmiHeader.biWidth = rc.right - rc.left;
bmpInf.bmiHeader.biHeight = rc.bottom - rc.top;
bmpInf.bmiHeader.biPlanes = 1;
bmpInf.bmiHeader.biBitCount = 24;
bmpInf.bmiHeader.biCompression = BI_RGB;
bmpInf.bmiHeader.biSizeImage = 0;
bmpInf.bmiHeader.biXPelsPerMeter=0;
bmpInf.bmiHeader.biYPelsPerMeter=0;
bmpInf.bmiHeader.biClrUsed=0;
bmpInf.bmiHeader.biClrImportant=0;
//---------------------这里的公式都是套用网上来的,---------------- BYTE *ptemp=new BYTE[((bmpInf.bmiHeader.biWidth*bmpInf.bmiHeader.biBitCount+31)/8)*bmpInf.bmiHeader.biHeight;
int Off;
int pitch=bmpInf.bmiHeader.biWidth%4;
int x=10;
int y=711;
Off=(y*bmpInf.bmiHeader.biWidth+x)*3+y*pitch; GetDIBits(hmemdc,hbitmap,0,(UINT)(bmpInf.bmiHeader.biHeight),ptemp,&bmpInf,DIB_RGB_COLORS);
BYTE B=ptemp[Off];
BYTE g=ptemp[Off+1];
BYTE r=ptemp[Off+2];
//==============这段是把BMP读到粘贴板的,也没有错误,显示的挺好...===========
::OpenClipboard(NULL);
EmptyClipboard();
SetClipboardData(CF_BITMAP, hbitmap);
CloseClipboard(); DeleteDC(hmemdc);
DeleteObject(hbitmap);
::ReleaseDC(NULL, hscrdc);
int x=10;
int y=711;
Off=(y*bmpInf.bmiHeader.biWidth+x)*3+y*pitch;明显,你计算像素的偏移量的算式是不正确的。像素偏移量的计算公示为24位图像的计算公示:Off=Y*Stride+X*3 ,这里Stride是Winodws为位图一行要满足四字节对齐后的自己大小。计算公式正式你自己代码里(bmpInf.bmiHeader.biWidth*bmpInf.bmiHeader.biBitCount+31)/8
确实是计算公式的问题,我现在改用了32,直接相乘就没问题了...很奇怪之前我也试过32位,但没成功
这个公式很头大...哎
请问下,第二个问题,我现在用的32位BMP图,VS2010,XPSP3系统,为什么颜色顺便成了RGBA,而不是BGRA...之前在很多地方都看到说,应该是反位的...to 1楼
不好意思,我后来又重新搞了下,问题并没有出在位图大小上面呢,还是计算公式上面的