截屏问题,测试通过给满分

我看你有戏 2008-11-19 01:07:42
截屏问题,测试通过给满分

我想用API截屏,保存到一个文件中

要求不用MFC类库

谢谢大家了

...全文
124 11 打赏 收藏 转发到动态 举报
写回复
用AI写文章
11 条回复
切换为时间正序
请发表友善的回复…
发表回复
lbjfeng 2008-11-19
  • 打赏
  • 举报
回复
啊,楼上的楼上,抢钱啊
lbjfeng 2008-11-19
  • 打赏
  • 举报
回复
#include "stdio.h"
#include "windows.h"
/************************************************************************/
/* hBitmap 为刚才的屏幕位图句柄
/* lpFileName 为需要保存的位图文件名
/************************************************************************/
int SaveBitmapToFile(HBITMAP hBitmap,LPSTR lpFileName)
{
HDC hDC; //设备描述表
int iBits;//当前显示分辨率下每个像素所占字节数
WORD wBitCount;//位图中每个像素所占字节数
DWORD dwPaletteSize=0;//定义调色板大小
DWORD dwBmBitsSize;//位图中像素字节大小
DWORD dwDIBSize;// 位图文件大小
DWORD dwWritten;//写入文件字节数
BITMAP Bitmap;//位图结构
BITMAPFILEHEADER bmfHdr; //位图属性结构
BITMAPINFOHEADER bi; //位图文件头结构
LPBITMAPINFOHEADER lpbi; //位图信息头结构 指向位图信息头结构
HANDLE fh;//定义文件句柄
HANDLE hDib;//分配内存句柄
HANDLE hPal;//分配内存句柄
HANDLE hOldPal=NULL;//调色板句柄

//计算位图文件每个像素所占字节数
hDC = CreateDC("DISPLAY",NULL,NULL,NULL);
iBits = GetDeviceCaps(hDC, BITSPIXEL) * GetDeviceCaps(hDC, PLANES);
DeleteDC(hDC);

if (iBits <= 1)
wBitCount = 1;
else if (iBits <= 4)
wBitCount = 4;
else if (iBits <= 8)
wBitCount = 8;
else if (iBits <= 24)
wBitCount = 24;
else if (iBits<=32)
wBitCount = 24;


//计算调色板大小
if (wBitCount <= 8)
dwPaletteSize = (1 << wBitCount) *sizeof(RGBQUAD);



//设置位图信息头结构
GetObject(hBitmap, sizeof(BITMAP), (LPSTR)&Bitmap);
bi.biSize = sizeof(BITMAPINFOHEADER);
bi.biWidth = Bitmap.bmWidth;
bi.biHeight = Bitmap.bmHeight;
bi.biPlanes = 1;
bi.biBitCount = wBitCount;
bi.biCompression = BI_RGB;
bi.biSizeImage = 0;
bi.biXPelsPerMeter = 0;
bi.biYPelsPerMeter = 0;
bi.biClrUsed = 0;
bi.biClrImportant = 0;
dwBmBitsSize = ((Bitmap.bmWidth *wBitCount+31)/32)* 4*Bitmap.bmHeight ;

//为位图内容分配内存
hDib = GlobalAlloc(GHND,dwBmBitsSize+dwPaletteSize+sizeof(BITMAPINFOHEADER));
lpbi = (LPBITMAPINFOHEADER)GlobalLock(hDib);
if (lpbi==NULL)
{
return 0;
}

*lpbi = bi;
// 处理调色板
hPal = GetStockObject(DEFAULT_PALETTE);
if (hPal)
{
hDC = GetDC(NULL);
hOldPal = ::SelectPalette(hDC, (HPALETTE)hPal, FALSE);
RealizePalette(hDC);
}
// 获取该调色板下新的像素值
GetDIBits(hDC, hBitmap, 0, (UINT) Bitmap.bmHeight,
(LPSTR)lpbi + sizeof(BITMAPINFOHEADER)+dwPaletteSize,
(LPBITMAPINFO)lpbi, DIB_RGB_COLORS);
//恢复调色板
if (hOldPal)
{
SelectPalette(hDC, (HPALETTE)hOldPal, TRUE);
RealizePalette(hDC);
ReleaseDC(NULL, hDC);
}
//创建位图文件
fh = CreateFile(lpFileName, GENERIC_WRITE,
0, NULL, CREATE_ALWAYS,
FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN, NULL);

if (fh == INVALID_HANDLE_VALUE)
return FALSE;

// 设置位图文件头
bmfHdr.bfType = 0x4D42; // "BM"
dwDIBSize = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER)+ dwPaletteSize + dwBmBitsSize;
bmfHdr.bfSize = dwDIBSize;
bmfHdr.bfReserved1 = 0;
bmfHdr.bfReserved2 = 0;
bmfHdr.bfOffBits = (DWORD)sizeof(BITMAPFILEHEADER) + (DWORD)sizeof(BITMAPINFOHEADER)+ dwPaletteSize;

// 写入位图文件头
WriteFile(fh, (LPSTR)&bmfHdr, sizeof(BITMAPFILEHEADER), &dwWritten, NULL);

// 写入位图文件其余内容
WriteFile(fh, (LPSTR)lpbi, dwDIBSize, &dwWritten, NULL);

//清除
GlobalUnlock(hDib);
GlobalFree(hDib);
CloseHandle(fh);

return 1;
}

HBITMAP GetCaptureBmp()
{
HDC hDC;
HDC MemDC;
BYTE* Data;
HBITMAP hBmp;
BITMAPINFO bi;

memset(&bi, 0, sizeof(bi));
bi.bmiHeader.biSize = sizeof(BITMAPINFO);
bi.bmiHeader.biWidth = GetSystemMetrics(SM_CXSCREEN);
bi.bmiHeader.biHeight = GetSystemMetrics(SM_CYSCREEN);
bi.bmiHeader.biPlanes = 1;
bi.bmiHeader.biBitCount = 24;

hDC = GetDC(NULL);
MemDC = CreateCompatibleDC(hDC);
hBmp = CreateDIBSection(MemDC, &bi, DIB_RGB_COLORS, (void**)&Data, NULL, 0);
SelectObject(MemDC, hBmp);
BitBlt(MemDC, 0, 0, bi.bmiHeader.biWidth, bi.bmiHeader.biHeight,hDC, 0, 0, SRCCOPY);
ReleaseDC(NULL, hDC);
DeleteDC(MemDC);
return hBmp;
}


void main()
{
HBITMAP hBmp;
hBmp = GetCaptureBmp();
SaveBitmapToFile(hBmp,"c:\\11.bmp");
}
qiuqiu173 2008-11-19
  • 打赏
  • 举报
回复
很好,刚好需要,谢了楼主 ^_^

顺便给大家黏贴吧
HBITMAP GetCaptureBmp()
{
HDC hDC;
HDC MemDC;
BYTE* Data;
HBITMAP hBmp;
BITMAPINFO bi;

memset(&bi, 0, sizeof(bi));
bi.bmiHeader.biSize = sizeof(BITMAPINFO);
bi.bmiHeader.biWidth = GetSystemMetrics(SM_CXSCREEN);
bi.bmiHeader.biHeight = GetSystemMetrics(SM_CYSCREEN);
bi.bmiHeader.biPlanes = 1;
bi.bmiHeader.biBitCount = 24;

hDC = GetDC(NULL);
MemDC = CreateCompatibleDC(hDC);
hBmp = CreateDIBSection(MemDC, &bi, DIB_RGB_COLORS, (void**)&Data, NULL, 0);
SelectObject(MemDC, hBmp);
BitBlt(MemDC, 0, 0, bi.bmiHeader.biWidth, bi.bmiHeader.biHeight,hDC, 0, 0, SRCCOPY);
ReleaseDC(NULL, hDC);
DeleteDC(MemDC);
return hBmp;
}
我看你有戏 2008-11-19
  • 打赏
  • 举报
回复
真是郁闷啊,还是没有满意的答案,火了
自己找到答案了

API截屏,C截屏,谁愿意去复制黏贴到这里来的,给分了...
http://www.nuli365.com/ReadCode.aspx?id=584
我看你有戏 2008-11-19
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 Chiyer 的回复:]
给你转一个


C/C++ code
(一)功能
实现了一个定时截取当前屏幕图像的小程序。

(二)准备工作
1)建立VC CONSOLE APPLICATION,选择MFC SUPPORT
2)在STDAFX.H文件中加入头文件:conio.h

(三)主程序
主程序代码如下:
char Filename[100];
int count = 0;

while(!_kbhit())//用户按键则退出
{
Sleep(5000);//挂起5秒

count ++;

[/Quote]


大哥要求不用MFC类库啊

WingForce 2008-11-19
  • 打赏
  • 举报
回复
呵呵,用GDI抓,不是所有的都能抓下来的
星羽 2008-11-19
  • 打赏
  • 举报
回复
给你转一个


(一)功能
实现了一个定时截取当前屏幕图像的小程序。

(二)准备工作
1)建立VC CONSOLE APPLICATION,选择MFC SUPPORT
2)在STDAFX.H文件中加入头文件:conio.h

(三)主程序
主程序代码如下:
char Filename[100];
int count = 0;

while(!_kbhit())//用户按键则退出
{
Sleep(5000);//挂起5秒

count ++;

sprintf(Filename, "%d.bmp", count);

Screen(Filename);//调用Screen函数
}
以上代码每隔5秒钟调用一次函数Screen,将当前屏幕保存到文件中。

(四)工作函数Screen
Screen实现了当前屏幕内容到bmp文件的拷贝。
源代码如下:
void Screen(char filename[])
{
CDC *pDC;//屏幕DC
pDC = CDC::FromHandle(GetDC(NULL));//获取当前整个屏幕DC
int BitPerPixel = pDC->GetDeviceCaps(BITSPIXEL);//获得颜色模式
int Width = pDC->GetDeviceCaps(HORZRES);
int Height = pDC->GetDeviceCaps(VERTRES);

cout << "当前屏幕色彩模式为" << BitPerPixel << "位色彩" << endl
<< "屏幕宽度:" << Width << endl
<< "屏幕高度:" << Height << endl << endl;

CDC memDC;//内存DC
memDC.CreateCompatibleDC(pDC);

CBitmap memBitmap, *oldmemBitmap;//建立和屏幕兼容的bitmap
memBitmap.CreateCompatibleBitmap(pDC, Width, Height);

oldmemBitmap = memDC.SelectObject(&memBitmap);//将memBitmap选入内存DC
memDC.BitBlt(0, 0, Width, Height, pDC, 0, 0, SRCCOPY);//复制屏幕图像到内存DC

//以下代码保存memDC中的位图到文件
BITMAP bmp;
memBitmap.GetBitmap(&bmp);//获得位图信息

FILE *fp = fopen(filename, "w+b");

BITMAPINFOHEADER bih = {0};//位图信息头
bih.biBitCount = bmp.bmBitsPixel;//每个像素字节大小
bih.biCompression = BI_RGB;
bih.biHeight = bmp.bmHeight;//高度
bih.biPlanes = 1;
bih.biSize = sizeof(BITMAPINFOHEADER);
bih.biSizeImage = bmp.bmWidthBytes * bmp.bmHeight;//图像数据大小
bih.biWidth = bmp.bmWidth;//宽度

BITMAPFILEHEADER bfh = {0};//位图文件头
bfh.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);//到位图数据的偏移量
bfh.bfSize = bfh.bfOffBits + bmp.bmWidthBytes * bmp.bmHeight;//文件总的大小
bfh.bfType = (WORD)0x4d42;

fwrite(&bfh, 1, sizeof(BITMAPFILEHEADER), fp);//写入位图文件头

fwrite(&bih, 1, sizeof(BITMAPINFOHEADER), fp);//写入位图信息头

byte * p = new byte[bmp.bmWidthBytes * bmp.bmHeight];//申请内存保存位图数据

GetDIBits(memDC.m_hDC, (HBITMAP) memBitmap.m_hObject, 0, Height, p,
(LPBITMAPINFO) &bih, DIB_RGB_COLORS);//获取位图数据

fwrite(p, 1, bmp.bmWidthBytes * bmp.bmHeight, fp);//写入位图数据

delete [] p;

fclose(fp);

memDC.SelectObject(oldmemBitmap);
}

(五)改进
可以在系统热键中加入自定义热键,进行动态的(按用户需要的)截屏操作。


我看你有戏 2008-11-19
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 weidong0210 的回复:]
是要截取最上面一个屏幕吗?
[/Quote]

截屏是指截取整个屏幕的图像
weidong0210 2008-11-19
  • 打赏
  • 举报
回复
是要截取最上面一个屏幕吗?
我看你有戏 2008-11-19
  • 打赏
  • 举报
回复
代码给一下吧,需要保存为bmp文件的哦
太乙 2008-11-19
  • 打赏
  • 举报
回复
http://www.aub.org.cn/C/Article178370.html

69,369

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧