C++截图并保存为文件
调用WindowsApi,使用Com组件,我也是借鉴加修改的,因为网上直接复制下来的并不能直接调用(HBITMAP这种东西就比较奇怪),以后当成工具调用就可以了,写了部分注释,就不一句句讲解了。
GetThumbImage()是用来调用截图的ScreenCapture类的,可以指定保存的文件名,截图的范围。
TBitmap* __fastcall TForm3::GetThumbImage()
{
TImage *img = NULL;
TBitmap *bitmap = new TBitmap();
HBITMAP hBitmap = NULL;
LPSTR addr = "ScreenCapture.png";
hBitmap = ScreenCapture(addr, 32, NULL);
::GetObject(hBitmap, sizeof(bitmap), (LPSTR)&bitmap);
bitmap->LoadFromFile(addr);
return bitmap;
}
HBITMAP TForm3::ScreenCapture(LPSTR filename ,WORD BitCount,LPRECT lpRect)
{
HBITMAP hBitmap;
// 显示器屏幕DC
HDC hScreenDC = CreateDC(L"DISPLAY", NULL, NULL, NULL);
HDC hmemDC = CreateCompatibleDC(hScreenDC);
// 显示器屏幕的宽和高
int ScreenWidth = GetDeviceCaps(hScreenDC, HORZRES);
int ScreenHeight = GetDeviceCaps(hScreenDC, VERTRES);
// 旧的BITMAP,用于与所需截取的位置交换
HBITMAP hOldBM;
// 保存位图数据
PVOID lpvpxldata;
// 截屏获取的长宽及起点
INT ixStart;
INT iyStart;
INT iX;
INT iY;
// 位图数据大小
DWORD dwBitmapArraySize;
// 几个大小
DWORD nBitsOffset;
DWORD lImageSize ;
DWORD lFileSize ;
// 位图信息头
BITMAPINFO bmInfo;
// 位图文件头
BITMAPFILEHEADER bmFileHeader;
// 写文件用
HANDLE hbmfile;
DWORD dwWritten;
// 如果LPRECT 为NULL 截取整个屏幕
if(lpRect == NULL)
{
ixStart = iyStart = 0;
iX = ScreenWidth;
iY =ScreenHeight;
}
else
{
ixStart = lpRect->left;
iyStart = lpRect->top;
iX = lpRect->right - lpRect->left;
iY = lpRect->bottom - lpRect->top;
}
// 创建BTIMAP
hBitmap = CreateCompatibleBitmap(hScreenDC, iX, iY);
// 将BITMAP选择入内存DC。
hOldBM = (HBITMAP)SelectObject(hmemDC, hBitmap);
// BitBlt屏幕DC到内存DC,根据所需截取的获取设置参数
BitBlt(hmemDC, 0, 0, iX, iY, hScreenDC, ixStart, iyStart, SRCCOPY);
// 将旧的BITMAP对象选择回内存DC,返回值为被替换的对象,既所截取的位图
hBitmap = (HBITMAP)SelectObject(hmemDC, hOldBM);
if(filename == NULL)
{
DeleteDC( hScreenDC);
DeleteDC(hmemDC);
return hBitmap;
}
// 为位图数据申请内存空间
dwBitmapArraySize = ((((iX*32) + 31) & ~31)>> 3)* iY;
lpvpxldata = HeapAlloc(GetProcessHeap(),HEAP_NO_SERIALIZE,dwBitmapArraySize);
ZeroMemory(lpvpxldata,dwBitmapArraySize);
// 添充 BITMAPINFO 结构
ZeroMemory(&bmInfo,sizeof(BITMAPINFO));
bmInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
bmInfo.bmiHeader.biWidth = iX;
bmInfo.bmiHeader.biHeight = iY;
bmInfo.bmiHeader.biPlanes = 1;
bmInfo.bmiHeader.biBitCount = BitCount;
bmInfo.bmiHeader.biCompression = BI_RGB;
// 添充 BITMAPFILEHEADER 结构
ZeroMemory(&bmFileHeader,sizeof(BITMAPFILEHEADER));
nBitsOffset = sizeof(BITMAPFILEHEADER) + bmInfo.bmiHeader.biSize;
lImageSize =
((((bmInfo.bmiHeader.biWidth * bmInfo.bmiHeader.biBitCount) + 31) & ~31)>> 3)
* bmInfo.bmiHeader.biHeight;
lFileSize = nBitsOffset + lImageSize;
bmFileHeader.bfType = "B"+("M"<<8);
bmFileHeader.bfSize = lFileSize;
bmFileHeader.bfOffBits = nBitsOffset;
// 获取DIB用于写入到文件
GetDIBits(hmemDC, hBitmap, 0, bmInfo.bmiHeader.biHeight,
lpvpxldata, &bmInfo, DIB_RGB_COLORS);
// 写文件
hbmfile = CreateFileA(filename,
GENERIC_WRITE,
FILE_SHARE_WRITE,
NULL,
CREATE_ALWAYS,
FILE_ATTRIBUTE_NORMAL,
NULL);
if(hbmfile == INVALID_HANDLE_VALUE)
{
MessageBoxA(NULL,"create file error","error",MB_OK);
}
WriteFile(hbmfile,&bmFileHeader,sizeof(BITMAPFILEHEADER),&dwWritten,NULL);
WriteFile(hbmfile,&bmInfo,sizeof(BITMAPINFO),&dwWritten,NULL);
WriteFile(hbmfile,lpvpxldata,lImageSize,&dwWritten,NULL);
CloseHandle(hbmfile);
// MessageBox(NULL,"文件写入成功","error",MB_OK);
// 释放内存,清除不同的DC。
// 这里没有删除BITMAP对象,需在显示完成后删除
HeapFree(GetProcessHeap(),HEAP_NO_SERIALIZE,lpvpxldata);
ReleaseDC(0, hScreenDC);
DeleteDC(hmemDC);
return hBitmap;
}声明:该文观点仅代表作者本人,入门客AI创业平台信息发布平台仅提供信息存储空间服务,如有疑问请联系rumenke@qq.com。
- 上一篇:没有了
- 下一篇:没有了
