利用window API实现matlab屏幕抓取函数
http://tech.ddvip.com 2007年07月21日 社区交流
内容摘要:结合如何用window API实现matlab屏幕抓取函数,介绍了在matlab中如何利用matlab与C/C++的接口,调用操作系统API,扩展matlab功能。
利用window API实现matlab屏幕抓取函数
本质上就是利用C语言调用window API函数来实现屏幕抓取功能,同时,必须处理好C语言与matlab接口问题和C语言中数组存储与matlab中数组存储的转化问题。
以下是C源程序,有详细的注释。
// matlab mex file to snap the screen
// compile to use>> mex screensnap.c user32.lib gdi32.lib
// usage:1, >>a=screensnap(0) %exclude the matlab window
// >>imshow(a);
// 2, >>a=screensnap(1); %include the matlab window
// >> imshow(a);
// designed by darnshong chenzushang@sina.com
// 2005,12,18
#include <windows.h>
#include <string.h>
#include "mex.h"
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
{
int cx,cy,recnum;
int dims[3],i,j,k;
char *pchar,*mloc;
bool bshowmatlab;//抓屏时是否屏蔽matlab主窗口
HWND hwin,hactw;
HDC dc,memdc;
RECT rect;
HBITMAP hbitm,hold;
BITMAPINFOHEADER binfoh;
if(nrhs!=1) //对输入参数进行检验
mexErrMsgTxt("Need 1 argument!
");
if(!mxIsDouble(prhs[0]))
mexErrMsgTxt("The input argument must be a numeric!
");
if(*(double*)(mxGetData(prhs[0]))==0)
bshowmatlab=false;
else
bshowmatlab=true;
hactw=GetForegroundWindow();//获取matlab的窗口句柄
hwin=GetDesktopWindow();//获取桌面窗口句柄
dc=GetWindowDC(hwin);//获取桌面窗口DC
GetWindowRect(hwin,&rect);//获取桌面窗口大小
cx=rect.right-rect.left;
cy=rect.bottom-rect.top;
mexPrintf("cx: %d cy: %d
!",cx,cy);
memdc=CreateCompatibleDC(dc);//创建与桌面窗口DC相适应的内存DC
mexPrintf("Handles: %d %d %d
!",hwin,dc,memdc);
hbitm=CreateCompatibleBitmap(dc,cx,cy);//创建相适应的位图
if(hbitm==0)
mexErrMsgTxt("Fail to create a compatible bitmap!
");
if (!(hold=SelectObject(memdc, hbitm))) //将新建的位图选入内存DC中
mexErrMsgTxt("Compatible Bitmap Selection!
");
// Hide the application window.
if(!bshowmatlab)
{
ShowWindow(hactw, SW_HIDE); //屏蔽matlab主窗口
Sleep(100);//延迟100ms,因为在屏蔽matlab主窗口的过程中不能抓屏
}
//Copy color data for the entire display into a
//bitmap that is selected into a compatible DC.
if (!BitBlt(memdc,0,0,cx,cy,dc,0,0,SRCCOPY)) //将桌面窗口DC拷贝到内存DC中
mexErrMsgTxt("Screen to Compat Blt Failed");
dims[0]=cy;//注意cx,cy的顺序
dims[1]=cx;
dims[2]=3;
plhs[0]=mxCreateNumericArray(3,dims,mxUINT8_CLASS,mxREAL);
//创建输出变量空间来传递图像数据
//由于是彩色图像,含RGB三分量,所以为三维数据
pchar=(char*)mxGetData(plhs[0]);
binfoh.biSize=sizeof(BITMAPINFOHEADER);
binfoh.biWidth=cx;
binfoh.biHeight=-cy;
binfoh.biPlanes=1;
binfoh.biBitCount=24;
binfoh.biCompression=BI_RGB;
binfoh.biSizeImage=0;
binfoh.biXPelsPerMeter=0;
binfoh.biYPelsPerMeter =0;
binfoh.biClrUsed=0;
binfoh.biClrImportant=0;
//配置位图信息头结构
mloc=(char*)mxMalloc(cx*cy*3);
//申请空间来存放图像数据 recnum=GetDIBits(memdc,hbitm,0,cy,mloc,(BITMAPINFO*)&binfoh,DIB_RGB_COLORS);
//将图像数据复制到mloc空间里
mexPrintf("Copyed %d lines %d
!",recnum,hbitm);
for(k=0;k<3;k++)
for(j=0;j<cy;j++)
for(i=0;i<cx;i++)
{
pchar[i*cy+j+k*cx*cy]=mloc[(j*cx+i)*3+2-k];
//由于matlab中数据存储是先列后行的,与C程序中先行后列不一样
//图像数据在复制到输出变量时必须进行适当的处理
}
mxFree(mloc);//释放申请的内存空间
SelectObject(hbitm,hold);
DeleteDC(memdc);
ReleaseDC(hwin,dc);
DeleteObject(hbitm);
//完成之后进行必要的处理防止内存泄漏
if(!bshowmatlab)
ShowWindow(hactw, SW_SHOW);
//恢复matlab主窗口的显示
}上述程序中以mx,mex开头的函数是matlab为方便mex文件的开发提供的函数,在mex.h文件中有声明,matlab的帮助系统中有详细的说明。运行结果
将上述源程序保存为screensnap.c文件,在matlab命令窗口中运行:mex screensnap.c user32.lib gdi32.lib
就可以产生一个screensnap.dll的动态链接库文件,然后该文件所在的目录加入matlab的搜索目录中,在matlab命令窗口中运行如下命令:
dat=screensnap(0);%屏蔽matlab窗口,如果不屏蔽,可用dat=screensnap(1);
imshow(dat);%显示图像则可以得到如下的结果

小结
通过以上示例可以看出,通过matlab与C的接口,我们可以充分利用C语言的优势,根据自身的需要,利用C语言调用操作系统API进行编程,扩展和丰富matlab函数,更好的发挥matlab功能。
来源:vckbase 作者:陈祖尚 责编:豆豆技术应用
正在加载评论...
- VC/VC++按钮设计专题
- VC/VC++ 菜单专题
- VC/VC++ 工具条专题
- VC/VC++ 对话框教程
- VC/VC++ 报表教程
- VC/VC++ 控件
- VC/VC++ GDI
- Visual Studio 2008
- VC/VC++ MFC教程
- VC/VC++ QQ
- VC/VC++ Socket编程
- VC/VC++ 钩子编程
- TangramMini组件应用教程
- VC/VC++ 窗体
- VC/VC++ ADO 教程
- Windows CE 教程
- VC/VC++ DLL(动态链接库)编程
- VC/VC++ PDFlib
- VC与MATLAB编程
- VC/VC++ DirectShow 教程
- VC++入门视频教程
- VC/VC++ COM组件设计与应用
- VC/VC++ ATL
- VC/VC++ WTL
- VC/VC++ 定制调试诊断工具和程序
- VC/VC++ 进程
- VC/VC++ Win32
- VC/VC++ WMI
- VC/VC++ 消息
- 更多VC/VC++专题……