社区
界面
帖子详情
用什么方法可以截取屏幕上指定区域的位图?
wbcnxa
2005-09-20 11:47:07
用什么方法可以截取屏幕上指定区域的位图?
...全文
386
5
打赏
收藏
用什么方法可以截取屏幕上指定区域的位图?
用什么方法可以截取屏幕上指定区域的位图?
复制链接
扫一扫
分享
转发到动态
举报
AI
作业
写回复
配置赞助广告
用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也可
windows平台下C++实现
屏幕
截取
(可
截取
指定
区域
/可显示鼠标)
windows平台下使用C++视频
屏幕
截取
功能,能够
截取
指定
区域
,能够开关鼠标的显示,工程下载下来可直接编译运行起来,配套的测试demo写的比较简单,可以根据自己的应用场景调用插件测试。
VC++
屏幕
截取
(窗口截图、选区截图)、
屏幕
拾色器、放大镜
VC++
屏幕
截取
(窗口截图、选区截图)、
屏幕
拾色器、放大镜~
C#
截取
屏幕
核心代码
C#
截取
屏幕
核心代码
自己总结的!!!
完全能用,测试过!
C#
截取
屏幕
代码 并且可以保存
支持VS打开 可以
截取
电脑
屏幕
并可以保存 我的资源里也有类似QQ抓屏的代码 有时间大家可以下载下来参考参考 共同学习。
VB6.0 截图软件
截取
全屏
截取
区域
自己照着做的截图软件,有
截取
全屏,
截取
区域
功能。
界面
15,980
社区成员
115,867
社区内容
发帖
与我相关
我的任务
界面
VC/MFC 界面
复制链接
扫一扫
分享
社区描述
VC/MFC 界面
社区管理员
加入社区
获取链接或二维码
近7日
近30日
至今
加载中
查看更多榜单
社区公告
暂无公告
试试用AI创作助手写篇文章吧
+ 用AI写文章