社区
界面
帖子详情
用什么方法可以截取屏幕上指定区域的位图?
wbcnxa
2005-09-20 11:47:07
用什么方法可以截取屏幕上指定区域的位图?
...全文
412
5
打赏
收藏
用什么方法可以截取屏幕上指定区域的位图?
用什么方法可以截取屏幕上指定区域的位图?
复制链接
扫一扫
分享
转发到动态
举报
写回复
配置赞助广告
用AI写文章
5 条
回复
切换为时间正序
请发表友善的回复…
发表回复
打赏红包
xhzxlqt
2005-12-05
打赏
举报
回复
这是一个保存整个屏幕的,你可以改为保存一部分,代码是BCB下的:
Ddraw.cpp从SDK里找去
先要:
//初始化DirectDraw环境,并实现DirectDraw功能
InitDDraw(lpDD,lpDDSPrimary)
最后要:
FreeDDraw(lpDD,lpDDSPrimary);
保存的CPP
bool Is555=true;
inline unsigned char GetRed(WORD color)
{
if( Is555 )
return (color>>7) & 0xff;
else
return (color>>8) & 0xff;
}
inline unsigned char GetGreen(WORD color)
{
if( Is555 )
return (color>>2) & 0xff;
else
return (color>>3) & 0xff;
}
inline unsigned char GetBlue(WORD color)
{
return (color & 0x1f) << 3;
}
bool SaveToBitmapFile(LPDIRECTDRAWSURFACE lpSurface, char* filename)
{
WORD* lpBuffer; // 表面指针
int nPitch; // 表面跨距
int nWidth, nHeight; // 表面宽高
///////////////
/////////////
HWND hwnd=GetActiveWindow();
// 打开文件s
FILE* fp;
if( (fp=fopen(filename, "wb")) != NULL )
{
// 锁定表面
DDSURFACEDESC ddsd;
ddsd.dwSize = sizeof(ddsd);
ShowWindow(hwnd,SW_MINIMIZE);
HRESULT ddrval = lpSurface->Lock( NULL, &ddsd, DDLOCK_WAIT, NULL );
// ddsd.lPitch//每行数据总字节数
// ShowMessage("RM:"+AnsiString(ddsd.ddpfPixelFormat.dwRBitMask)+
// "GM:"+AnsiString(ddsd.ddpfPixelFormat.dwGBitMask)
// +"BM:"+AnsiString(ddsd.ddpfPixelFormat.dwBBitMask)
// +"lPitch:"+AnsiString(ddsd.lPitch));
if( ddrval == DD_OK )
{
lpBuffer = (WORD *)ddsd.lpSurface;
nWidth = ddsd.dwWidth;
nHeight = ddsd.dwHeight;
nPitch = ddsd.lPitch >> 1; //lPitch以Byte为单位,GraphPitch以WORD为单位。所以GraphPitch = lPitch / 2;
if(ddsd.ddpfPixelFormat.dwBBitMask==31)Is555=false;
}
// 保存文件头
fputc(0x42,fp);
fputc(0x4d,fp);
fputc( (nWidth * nHeight * 3 + 0x36)&0xff,fp);
fputc(((nWidth * nHeight * 3 + 0x36)>>8)&0xff,fp);
fputc(((nWidth * nHeight * 3 + 0x36)>>16)&0xff,fp);
fputc(((nWidth * nHeight * 3 + 0x36)>>24)&0xff,fp);
fputc(0,fp);fputc(0,fp);
fputc(0,fp);fputc(0,fp);
fputc(0x36,fp);
fputc(0,fp);fputc(0,fp);fputc(0,fp);
// 保存文件信息
BITMAPINFOHEADER Header;
Header.biSize = sizeof(BITMAPINFOHEADER);// 结构的大小
Header.biWidth = nWidth; // 宽
Header.biHeight = nHeight;// 高
Header.biPlanes = 1; // 固定
Header.biBitCount = 24; // 颜色数
Header.biCompression = BI_RGB; // 是否压缩
Header.biSizeImage = nWidth * nHeight * 3;// 图片的大小
Header.biXPelsPerMeter = 0;
Header.biYPelsPerMeter = 0;
Header.biClrUsed = 0;
Header.biClrImportant = 0;
fwrite(&Header, Header.biSize, 1, fp);
// 写入具体内容(从下向上存放)
fseek(fp, 0x36, SEEK_SET);
switch(ddsd.ddpfPixelFormat.dwRGBBitCount)
{
case 8:
{
BYTE *tem=(BYTE *)ddsd.lpSurface;
PALETTEENTRY entry[256];
HDC hScrDC=CreateDC("DISPLAY",NULL,NULL,NULL);
::GetSystemPaletteEntries(hScrDC,0,256,entry);
for(int y=(int)nHeight-1;y>=0;y--)
{
for(int x=0;x<(int)nWidth;x++)
{
fputc(entry[tem[x+ddsd.lPitch*y]].peBlue,fp);
fputc(entry[tem[x+ddsd.lPitch*y]].peGreen,fp);
fputc(entry[tem[x+ddsd.lPitch*y]].peRed,fp);
}
}
DeleteDC(hScrDC);
break;
}
case 16:
{ WORD word;
lpBuffer += nWidth * (nHeight - 1);
for(int i=0; i<nHeight; i++)
{
for(int j=0; j<nWidth; j++)
{
word = *lpBuffer;
fputc( GetBlue( word ), fp); // 蓝
fputc( GetGreen( word ), fp); // 绿
fputc( GetRed( word ), fp); // 红
lpBuffer++;
}
lpBuffer -= nPitch*2; // 指针转到上一行的开始
}
break;
}
case 24:
// case 32:
{
BYTE *tem=(BYTE *)ddsd.lpSurface;
tem+=nWidth * (nHeight - 1)*3;
// ShowMessage(AnsiString(ddsd.lPitch));
for(int y=(int)nHeight-1;y>=0;y--)
{
for(int x=0;x<(int)nWidth;x++)
{
fputc(*tem++,fp);
fputc(*tem++,fp);
fputc(*tem++,fp);
}
tem-=ddsd.lPitch*2;
}
break;
}
case 32:
{
BYTE *tem=(BYTE *)ddsd.lpSurface;
tem+=nWidth * (nHeight - 1)*4;
// ShowMessage(AnsiString(ddsd.lPitch));
for(int y=(int)nHeight-1;y>=0;y--)
{
for(int x=0;x<(int)nWidth;x++)
{
fputc(*tem++,fp);
fputc(*tem++,fp);
fputc(*tem++,fp);
tem++;
}
tem-=ddsd.lPitch*2;
}
break;
}
}//end switch
fclose(fp);
// 解锁表面
ddrval = lpSurface->Unlock( NULL );
PostMessage(hwnd,WM_QUIT,0,0);
return true;
}
return false;
}
wbcnxa
2005-09-21
打赏
举报
回复
这些方法都是copy特定窗口位图。我想要拷贝屏幕上任意指定区域的位图,其实就是屏幕抓图。
pomelowu
2005-09-20
打赏
举报
回复
获得屏幕DC,然后BitBlt。仔细看BitBlt的参数就知道了。
bobob
2005-09-20
打赏
举报
回复
HBITMAP CopyDCToBitmap(HDC hScrDC, LPRECT lpRect)
{
HDC hMemDC; // 屏幕和内存设备描述表
HBITMAP hBitmap,hOldBitmap; // 位图句柄
int nX, nY, nX2, nY2; // 选定区域坐标
int nWidth, nHeight; // 位图宽度和高度
if (IsRectEmpty(lpRect)) // 确保选定区域不为空矩形
return NULL;
// 获得选定区域坐标
nX = lpRect->left;
nY = lpRect->top;
nX2 = lpRect->right;
nY2 = lpRect->bottom;
nWidth = nX2 - nX;
nHeight = nY2 - nY;
hMemDC = CreateCompatibleDC(hScrDC);//为屏幕设备描述表创建兼容的内存设备描述表
// 创建一个与屏幕设备描述表兼容的位图
float factor = 1.0f;
hBitmap = CreateCompatibleBitmap(hScrDC, nWidth, nHeight);
while(!hBitmap)
{
factor -= 0.05f;
hBitmap = CreateCompatibleBitmap(hScrDC, (int)(nWidth*factor), (int)(nHeight*factor));
}
// 把新位图选到内存设备描述表中
hOldBitmap = (HBITMAP)SelectObject(hMemDC, hBitmap);
// 把屏幕设备描述表拷贝到内存设备描述表中
StretchBlt(hMemDC,0,0,nWidth,nHeight,hScrDC,nX,nY,nWidth,nHeight,SRCCOPY);
//BitBlt(hMemDC, 0, 0, nWidth, nHeight,hScrDC, nX, nY, SRCCOPY);
//得到屏幕位图的句柄
hBitmap = (HBITMAP)SelectObject(hMemDC, hOldBitmap);
//清除
// DeleteDC(hScrDC);
DeleteDC(hMemDC);
DeleteObject(hOldBitmap);
// 返回位图句柄
return hBitmap;
}
xhzxlqt
2005-09-20
打赏
举报
回复
Direct也可
window
屏幕
截图
本文介绍了一种在Windows环境下通过编程实现
屏幕
截图的
方法
,并详细解释了如何将
截取
的图片保存为
位图
文件的全过程。文章包括两个核心函数:CopyScreenToBitmap用于
截取
屏幕
指定
区域
,SaveBitmapToFile用于将
位图
保存到文件。
基于MFC的截屏和以
位图
保存的函数
本文介绍如何使用VC++进行
屏幕
截图,并提供了将截图保存为
位图
文件的
方法
。通过简单的函数调用,可以轻松实现
屏幕
区域
的选择性截图,并将
截取
的画面保存到
指定
路径。
VC
屏幕
截图并保存为bmp文件
本文介绍了一种简单的
屏幕
截图
方法
,通过两个核心函数实现:CopyScreenToBitmap用于将
屏幕
指定
区域
转化为
位图
,SaveBitmapToFile则负责将
位图
保存为文件。文章提供了具体的代码示例,包括如何
截取
当前窗口及全屏截图。
屏幕
及窗口拷贝
本文介绍了一种在Windows环境下将
屏幕
或
指定
窗口
区域
转换为
位图
的
方法
。通过使用GDI函数,如CreateDC和BitBlt等,实现了两种功能:一是
截取
整个
屏幕
;二是
截取
指定
窗口的客户区或整个窗口。
界面
15,976
社区成员
115,866
社区内容
发帖
与我相关
我的任务
界面
VC/MFC 界面
复制链接
扫一扫
分享
社区描述
VC/MFC 界面
社区管理员
加入社区
获取链接或二维码
近7日
近30日
至今
加载中
查看更多榜单
社区公告
暂无公告
试试用AI创作助手写篇文章吧
+ 用AI写文章