MATLAB抓屏例子临时

摘要 :结合如何用window API实现matlab屏幕抓取函数,介绍了在matlab中如何利用matlab与C/C++的接口,调用操作系统API,扩展matlab功能。

  引言

  MATLAB 产品家族是美国 MathWorks公司开发的用于概念设计,算法开发,建模仿真,实时实现的理想的集成环境。由于其完整的专业体系和先进的设计 开发思路,使得 MATLAB 在多种领域都有广阔的应用空间。

  尽管MATLAB在科学研究以及工业技术开发方面有着极为广泛的应用,但是它也不是万能的。在某些场合下,MATLAB自身携带的函数及其组合并无法完全满足用户的要求,而必须通过调用操作系统的API函数来实现。MATLAB在设计时已经考虑到这点,为我们提供了mex命令,可用于将调用操作系统API函数的C程序编译成DLL文件,也就是MEX文件,使之成为MATLAB的一个扩展函数。这样,我们在MATLAB环境下编程时就可以直接调用该扩展函数,达到间接调用操作系统API函数的目的。本文将通过如何为MATLAB编写屏幕抓取函数来演示上述过程。

  MEX接口

  MEX是MATLAB Executable的缩写,也就是可以在MATLAB中执行。这是MATLAB和其他主要编程语言如C/C++,FORTRAN的接口。普通的C/C++或是FORTRAN源程序,只要加上一个特殊的接口函数,就能通过MATLAB里的MEX命令编译成一种特殊的动态链接库函数,而这种函数可以在MATLAB环境下编程时直接调用,与MATLAB内嵌的函数一样。这个特殊的接口函数相当于C程序中的main函数,是程序的入口,程序的执行就是从这个入口函数开始的。其原型为

  void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])

  其中,参数nlhs和nrhs为输出和输入变量的数目,参数plhs和prhs为输出和输入变量指针的指针,prhs是长度为nrhs的输入变量的指针数组,plhs是长度为nlhs的输出变量的指针数组。

利用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  [email protected]
// 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功能。

时间: 2024-10-08 02:43:12

MATLAB抓屏例子临时的相关文章

ASM (Android Screen Monitor) Android真机抓屏

Android 真机抓屏,你的手机连接电脑,真机测试并将你的手机屏幕实时显示在PC上,演示分享效果杠杠的.废话不多说了,直入主题: 1.下载 Android Screen Monitor 点击链接下载:http://code.google.com/p/Android-screen-monitor/ <1>将下载的 ASM_2_50.zip 压缩包解压得到 asm.jar: <2>将 asm.jar 复制到 C:\Users\kc28\AppData\Local\Android\sd

一款抓屏工具FSCapture 注册码 序列号 SERIAL(转)

FSCapture是一款抓屏工具,附带的其他两个小功能:取色器和屏幕放大镜.对抓取的图像提供缩放.旋转.减切.颜色调整等功能.只要点点鼠标就能随心抓取屏幕上的任何东西,拖放支持可以直接从系统.浏览器或其他程序中导入图片. 取色器 现在网上各式各样的取色器应该不少了,包括之前一直用的蓝色经典推荐的ColorSPY, Firefox下还有一个专门的取色器扩展ColorZilla,这些都是很好的软件.但自从使用了FS Capture之后,这些我都很少用到了.原因很简单,各种取色软件的功能都大同小异,F

分享非常有用的Java程序(关键代码)(七)---抓屏程序

原文:分享非常有用的Java程序(关键代码)(七)---抓屏程序 import java.awt.Dimension; import java.awt.Rectangle; import java.awt.Robot; import java.awt.Toolkit; import java.awt.image.BufferedImage; import javax.imageio.ImageIO; import java.io.File; ... public void captureScre

Windows抓屏技术

Windows桌面共享中一些常见的抓屏技术 1. BitBlt   我想做Windows开发应该都知道这个API, 它能实现DC间的内容拷贝, 如果我们把源DC指定成Monitor DC或是桌面DC, 它就能实现抓屏功能. 对于通过这种方式的抓屏, 有2点需要特别提醒: a. 在XP下我们可以通过最后的拷贝标志来控制是否拷贝layered window, 只有SRCCPY表示拷贝内容不包含layered window, 如果是SRCCPY | CAPTUREBLT表示拷贝包括Layered wi

MATLAB绘图及例子总结

MATLAB绘图及例子总结 二维图 例 1 X1=[1,2,4,6,7,8,10,11,12,14,16,17,18,20]; Y1=[1,2,4,6,7,8,10,10,8,7,6,4,2,1]; figure(1) plot(X1,Y1,'o','MarkerSize',15) X2=1:20; Y2=log(X2); figure(2) plot(X2,Y2,'o','MarkerSize',15) 结果: 例 2 X1=(0:12)*pi/6; Y1=cos(3*X1); X2=(0:3

linux 抓屏截图

gnome-screenshot [选项...] 抓取屏幕的图片 帮助选项: -h, –help 显示帮助选项 –help-all 显示全部帮助选项 –help-gtk 显示 GTK+ 选项 应用程序选项: -w, –window 抓取窗口,而不是整个屏幕 -a, –area 抓取屏幕的一个区域,而不是整个屏幕 -b, –include-border 抓图中包含窗口边框 -B, –remove-border 去除屏幕截图的窗口边框 -d, –delay=秒 在指定延迟后抓图[以秒计] -e, –

【原创】调用系统函数里面蓝屏例子

IRQL_NOT_LESS_OR_EQUAL (a) An attempt was made to access a pageable (or completely invalid) address at aninterrupt request level (IRQL) that is too high. This is usuallycaused by drivers using improper addresses.If a kernel debugger is available get

无显示屏的开发板抓屏

1,  命令获取当前屏幕截图: adb shell cd dev/graphics/ gsnap /data/XXX.png fb0 然后把XXX.png拷贝出来查看即可. 2,  保持屏幕常亮的命令 adb shell svc power stayon [true|false|usb|ac] 设置屏幕的常亮,true保持常亮,false不保持,usb当插入usb时常亮,ac当插入电源时常亮

Java抓屏程序代码

原文:http://www.open-open.com/code/view/1422262655200 import java.awt.Dimension; import java.awt.Rectangle; import java.awt.Robot; import java.awt.Toolkit; import java.awt.image.BufferedImage; import javax.imageio.ImageIO; import java.io.File; ... publ