看了一下屏幕截取的代码 发现了如下的新东西
HBITMAP BmpScreen = CreateCompatibleBitmap(hdc,GetDeviceCaps(hdc, HORZRES),GetDeviceCaps(hdc, VERTRES));
SelectObject(CompatibleHDC, BmpScreen);//该函数选择一对象到指定的设备上下文环境中,该新对象替换先前的相同类型的对象。
BitBlt(CompatibleHDC,0,0,GetDeviceCaps(hdc, HORZRES), GetDeviceCaps(hdc, VERTRES),hdc,0,0,SRCCOPY);
//该函数对指定的源设备环境区域中的像素进行位块(bit_block)转换,以传送到目标设备环境。
在后面的读取图片时可以被广泛使用
代码:
#include
HANDLE DDBtoDIB( HBITMAP bitmap, DWORD dwCompression, HPALETTE hPal,DWORD * sizeimage) ;
BOOL CapScreen(LPTSTR FileName);//截屏函数
HANDLE DDBtoDIB( HBITMAP bitmap, DWORD dwCompression, HPALETTE hPal,DWORD * sizeimage)
{
BITMAP bm;
BITMAPINFOHEADER bi;
LPBITMAPINFOHEADER lpbi;
DWORD dwLen;
HANDLE hDib;
HANDLE handle;
HDC hdc;
//不支持BI_BITFIELDS类型
if( dwCompression == BI_BITFIELDS )
return NULL;
//如果调色板为空,则用默认调色板
if (hPal==NULL)
hPal = (HPALETTE) GetStockObject(DEFAULT_PALETTE );
//获取位图信息
GetObject(bitmap,sizeof(bm),(LPSTR)&bm);//该函数得到指定图形对象的信息,根据图形对象,函数把填满的或结构,或表项(用于逻辑调色板)数目放入一个指定的缓冲区。
//初始化位图信息头
bi.biSize = sizeof(BITMAPINFOHEADER);
bi.biWidth = bm.bmWidth;
bi.biHeight = bm.bmHeight;
bi.biPlanes = 1;
bi.biBitCount = bm.bmPlanes * bm.bmBitsPixel;
bi.biCompression = dwCompression;
bi.biSizeImage = 0;
bi.biXPelsPerMeter = 0;
bi.biYPelsPerMeter = 0;
bi.biClrUsed = 0;
bi.biClrImportant = 0;
//计算信息头及颜色表大小
int ncolors = (1 << bi.biBitCount); if( ncolors> 256 )
ncolors = 0;
dwLen = bi.biSize + ncolors * sizeof(RGBQUAD);
// we need a device context to get the dib from
hdc = GetDC(NULL);
hPal = SelectPalette(hdc,hPal,FALSE);
RealizePalette(hdc);
//为信息头及颜色表分配内存
hDib = GlobalAlloc(GMEM_FIXED,dwLen);
if (!hDib){
SelectPalette(hdc,hPal,FALSE);
ReleaseDC(NULL,hdc);
return NULL;
}
lpbi = (LPBITMAPINFOHEADER)hDib;
*lpbi = bi;
//调用 GetDIBits 计算图像大小
GetDIBits(hdc, bitmap, 0L, (DWORD)bi.biHeight,
(LPBYTE)NULL, (LPBITMAPINFO)lpbi, (DWORD)DIB_RGB_COLORS );
bi = *lpbi;
//图像的每一行都对齐(32bit)边界
if (bi.biSizeImage == 0){
bi.biSizeImage = ((((bi.biWidth * bi.biBitCount) + 31) & ~31) / 8)
* bi.biHeight;
if (dwCompression != BI_RGB)
bi.biSizeImage = (bi.biSizeImage * 3) / 2;
}
//重新分配内存大小,以便放下所有数据
dwLen += bi.biSizeImage;
if (handle = GlobalReAlloc(hDib, dwLen, GMEM_MOVEABLE))
hDib = handle;
else{
GlobalFree(hDib);
//重选原始调色板
SelectPalette(hdc,hPal,FALSE);
ReleaseDC(NULL,hdc);
return NULL;
}
//获取位图数据
lpbi = (LPBITMAPINFOHEADER)hDib;
//最终获得的DIB
BOOL bgotbits = GetDIBits( hdc, bitmap,
0L, //扫描行起始处
(DWORD)bi.biHeight, //扫描行数
(LPBYTE)lpbi //位图数据地址
+ (bi.biSize + ncolors * sizeof(RGBQUAD)),
(LPBITMAPINFO)lpbi, //位图信息地址
(DWORD)DIB_RGB_COLORS); //颜色板使用RGB
if( !bgotbits )
{
GlobalFree(hDib);
SelectPalette(hdc,hPal,FALSE);
ReleaseDC(NULL,hdc);
return NULL;
}
SelectPalette(hdc,hPal,FALSE);
ReleaseDC(NULL,hdc);
*sizeimage=bi.biSizeImage;
return hDib;
}
BOOL CapScreen(LPTSTR FileName)
{
DWORD sizeimage;
HDC hdc = CreateDC("DISPLAY", NULL, NULL, NULL); //创建环境
HDC CompatibleHDC = CreateCompatibleDC(hdc); //在hdc的基础上面创建新的环境
HBITMAP BmpScreen = CreateCompatibleBitmap(hdc,GetDeviceCaps(hdc, HORZRES),GetDeviceCaps(hdc, VERTRES));
SelectObject(CompatibleHDC, BmpScreen);//该函数选择一对象到指定的设备上下文环境中,该新对象替换先前的相同类型的对象。
BitBlt(CompatibleHDC,0,0,GetDeviceCaps(hdc, HORZRES), GetDeviceCaps(hdc, VERTRES),hdc,0,0,SRCCOPY);
//该函数对指定的源设备环境区域中的像素进行位块(bit_block)转换,以传送到目标设备环境。
HANDLE pbitmapwithoutfileh=DDBtoDIB(BmpScreen, BI_RGB,0,&sizeimage);
BITMAPFILEHEADER bfh;
//设置位图信息头结构
bfh.bfType = ((WORD)('M'<< 8)|'B');
bfh.bfReserved1 = 0;
bfh.bfReserved2 = 0;
bfh.bfSize = 54+sizeimage;
bfh.bfOffBits = 54;
//创建位图文件
HANDLE hFile=CreateFile(FileName,GENERIC_WRITE,0,0,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,0);
DWORD dwWrite;
// 写入位图文件头
WriteFile(hFile,&bfh,sizeof(BITMAPFILEHEADER),&dwWrite,NULL);
// 写入位图文件其余内容
WriteFile(hFile,pbitmapwithoutfileh,bfh.bfSize,&dwWrite,NULL);
DeleteDC(hdc);
DeleteDC(CompatibleHDC);
//CloseHandle(CompatibleHDC);
return true;
}
int main(void)
{
CapScreen("desktop.jpg");
return 0;
}