当前位置:首页
开发技术指南» 文章正文
    引言:

 ·有关在控件中弹出界面的问题    »显示摘要«
    摘要: 我想开发一个控件供其它软件使用,该控件要做到:控件中有两个部分(相当于有两个form),在一个部分上点击按钮,弹出另一个部分(相当于在form1上点击一按钮,弹出form2)。我现在在只有usercontrol1的情况下应该怎样添加另一部分(相当于form2),以及添加之后如何写按钮的click程序,使之可以生成达到条件的控件。 ......
 ·总有一天要轮到你[zt]    »显示摘要«
    摘要: 总有一天要轮到你 发言人:龙卷风 总有一天要轮到你 有一天, 工人下岗了。 你高兴, 改革么就得有人付出。 有一天, 农民破产了。 你不屑, 天下最笨的就是他们。 有一天, 城管没收了小商贩的三轮车。 你开心, 前一天他的三轮车险些刮伤我的别克。 有一天, 交不起学费的孩子失了学。 你不解, 我的孩子上学都是在外国。 有一天, 股民被套。 你窃喜, 我就是那圈钱的。 有一天, 哥们在红灯区......


【问】如何对视频文件抓图

视频文件是用MCI指令打开的,并重定向到PictureBox控件,  
  然后使用MCI   Pause指令暂停,当用SavePicture命令企图保存图像时却找不到图像?  
  不知为何?我想此时视频输出可能和PictureBox不是同一个层?  
  那该如何才能抓图呢?(应该是某个API吧?)  
  另外,视频文件可能是各种格式(包括RM),所以不是所有的MCI指令都通用。  
 

NO.1   作者: SoHo_Andy

VB   捕捉屏幕图象  
   
  api函数声明:  
  Private   Declare   Function   ReleaseDC   Lib   "user32"   (ByVal   hwnd   As   Long,   ByVal   hdc   As   Long)   As   Long  
  Private   Declare   Function   OpenClipboard   Lib   "user32"   (ByVal   hwnd   As   Long)   As   Long  
  Private   Declare   Function   EmptyClipboard   Lib   "user32"   ()   As   Long  
  Private   Declare   Function   SetClipboardData   Lib   "user32"   (ByVal   wFormat   As   Long,   ByVal   hMem   As   Long)   As   Long  
  Private   Declare   Function   SelectObject   Lib   "gdi32"   (ByVal   hdc   As   Long,   ByVal   hObject   As   Long)   As   Long  
  Private   Declare   Function   DeleteDC   Lib   "gdi32"   (ByVal   hdc   As   Long)   As   Long  
  Private   Declare   Function   BitBlt   Lib   "gdi32"   (ByVal   hDestDC   As   Long,   ByVal   x   As   Long,   ByVal   y   As   Long,   ByVal   nWidth   As   Long,   ByVal   nHeight   As   Long,   ByVal   hSrcDC   As   Long,   ByVal   xSrc   As   Long,   ByVal   ySrc   As   Long,   ByVal   dwRop   As   Long)   As   Long  
  Private   Declare   Function   CreateDC   Lib   "gdi32"   Alias   "CreateDCA"   (ByVal   lpDriverName   As   String,   ByVal   lpDeviceName   As   String,   ByVal   lpOutput   As   String,   lpInitData   As   Long)   As   Long  
  Private   Declare   Function   CreateCompatibleDC   Lib   "gdi32"   (ByVal   hdc   As   Long)   As   Long  
  Private   Declare   Function   CreateCompatibleBitmap   Lib   "gdi32"   (ByVal   hdc   As   Long,   ByVal   nWidth   As   Long,   ByVal   nHeight   As   Long)   As   Long  
  Private   Declare   Function   CloseClipboard   Lib   "user32"   ()   As   Long  
   
  函数:  
  Sub   ScrnCap(Lt,   ,   Rt,   Bot)  
          rWidth   =   Rt   -   Lt  
          rHeight   =   Bot   -    
          SourceDC   =   CreateDC("DISPLAY",   0,   0,   0)  
          DestDC   =   CreateCompatibleDC(SourceDC)  
          BHandle   =   CreateCompatibleBitmap(SourceDC,   rWidth,   rHeight)  
          SelectObject   DestDC,   BHandle  
          BitBlt   DestDC,   0,   0,   rWidth,   rHeight,   SourceDC,   Lt,   ,   &HCC0020  
          Wnd   =   Screen.ActiveForm.hwnd  
          OpenClipboard   Wnd  
          EmptyClipboard  
          SetClipboardData   2,   BHandle  
          CloseClipboard  
          DeleteDC   DestDC  
          ReleaseDC   DHandle,   SourceDC  
  End   Sub  
   
  以下的示例把屏幕图象捕捉后,放到Picture1   中。  
  Sub   Command1_Click()  
          Form1.Visible   =   False  
          ScrnCap   0,   0,   640,   480  
          Form1.Visible   =   True  
          Picture1   =   Clipboard.GetData()  
  End   Sub

NO.2   作者: cso

不可以用这样的方法,造成这样的原因是Video   Overlay(视频覆盖,也有的叫视频重叠),这主要是通过“视频覆盖”,显示卡就会在当前桌面上绘制一个新的图像层来显示视频图像,这也正是为什么我们可以在电脑的桌面上开一个小窗口播放视频节目以及VCD/DVD的原因。由于这个图像层有自己的显示设置,即使你通过调整显示卡的亮度或者对比度使桌面显示效果看起来不错,但这对DVD等视频播放的效果却没有一点作用。

NO.3   作者: MSTOP

我抓屏试过,但是,抓视频却没有试过.  
  将   AutoRedraw   设置为   True   试试看.  
  还有,试取IMAGE属性试试看.

NO.4   作者: goodname008

  临时写了一个,测试通过。  
    在窗体上加2个PictureBox和3个Command。  
   
  Option   Explicit  
  Private   Declare   Function   mciSendString   Lib   "winmm.dll"   Alias   "mciSendStringA"   (ByVal   lpstrCommand   As   String,   ByVal   lpstrReturnString   As   String,   ByVal   uReturnLength   As   Long,   ByVal   hwndCallback   As   Long)   As   Long  
  Private   Declare   Function   CreateDC   Lib   "gdi32"   Alias   "CreateDCA"   (ByVal   lpDriverName   As   String,   ByVal   lpDeviceName   As   String,   ByVal   lpOutput   As   String,   lpInitData   As   Long)   As   Long  
  Private   Declare   Function   CreateCompatibleBitmap   Lib   "gdi32"   (ByVal   hdc   As   Long,   ByVal   nWidth   As   Long,   ByVal   nHeight   As   Long)   As   Long  
  Private   Declare   Function   CreateCompatibleDC   Lib   "gdi32"   (ByVal   hdc   As   Long)   As   Long  
  Private   Declare   Function   SelectObject   Lib   "gdi32"   (ByVal   hdc   As   Long,   ByVal   hObject   As   Long)   As   Long  
  Private   Declare   Function   BitBlt   Lib   "gdi32"   (ByVal   hDestDC   As   Long,   ByVal   X   As   Long,   ByVal   Y   As   Long,   ByVal   nWidth   As   Long,   ByVal   nHeight   As   Long,   ByVal   hSrcDC   As   Long,   ByVal   xSrc   As   Long,   ByVal   ySrc   As   Long,   ByVal   dwRop   As   Long)   As   Long  
  Private   Declare   Function   OpenClipboard   Lib   "user32"   (ByVal   hwnd   As   Long)   As   Long  
  Private   Declare   Function   EmptyClipboard   Lib   "user32"   ()   As   Long  
  Private   Declare   Function   SetClipboardData   Lib   "user32"   (ByVal   wFormat   As   Long,   ByVal   hMem   As   Long)   As   Long  
  Private   Declare   Function   CloseClipboard   Lib   "user32"   ()   As   Long  
  Private   Declare   Function   DeleteDC   Lib   "gdi32"   (ByVal   hdc   As   Long)   As   Long  
  Private   Declare   Function   ReleaseDC   Lib   "user32"   (ByVal   hwnd   As   Long,   ByVal   hdc   As   Long)   As   Long  
  Private   Declare   Function   GetWindowRect   Lib   "user32"   (ByVal   hwnd   As   Long,   lpRect   As   RECT)   As   Long  
  Private   Const   CCHDEVICENAME   =   32  
  Private   Const   CCHFORMNAME   =   32  
  Private   Type   RECT  
          Left   As   Long  
            As   Long  
          Right   As   Long  
          Bottom   As   Long  
  End   Type  
   
  Private   Sub   Command1_Click()  
  mciSendString   "close   avi",   0,   0,   0  
  mciSendString   "open   c:\123.avi   alias   avi   parent   "   &   Picture1.hwnd   &   "   style   child",   0,   0,   0  
  mciSendString   "play   avi",   0,   0,   0  
  End   Sub  
   
  Private   Sub   Command2_Click()  
  mciSendString   "pause   avi",   0,   0,   0  
  End   Sub  
   
    将屏幕中指定区域的图像复制到剪贴板  
    例:   ScreenCapture   0,   0,   Screen.Width   /   15,   Screen.Height   /   15  
            object.Picture   =   Clipboard.GetData()  
  Function   ScreenCapture(ByVal   Left   As   Integer,   ByVal     As   Integer,   ByVal   Right   As   Integer,   ByVal   Bottom   As   Integer)   As   Boolean  
  Dim   rWidth   As   Integer,   rHeight   As   Integer  
  Dim   SourceDC   As   Long,   DestDC   As   Long,   bHandle   As   Long,   dHandle   As   Long,   wnd   As   Long  
  rWidth   =   Right   -   Left  
  rHeight   =   Bottom   -    
  SourceDC   =   CreateDC("DISPLAY",   0,   0,   0)  
  DestDC   =   CreateCompatibleDC(SourceDC)  
  bHandle   =   CreateCompatibleBitmap(SourceDC,   rWidth,   rHeight)  
  SelectObject   DestDC,   bHandle  
  BitBlt   DestDC,   0,   0,   rWidth,   rHeight,   SourceDC,   Left,   ,   &HCC0020  
  wnd   =   Screen.ActiveForm.hwnd  
  OpenClipboard   wnd  
  EmptyClipboard  
  ScreenCapture   =   SetClipboardData(2,   bHandle)  
  CloseClipboard  
  DeleteDC   DestDC  
  ReleaseDC   dHandle,   SourceDC  
  End   Function  
   
  Private   Sub   Command3_Click()  
  Dim   picRect   As   RECT  
  GetWindowRect   Picture1.hwnd,   picRect  
  ScreenCapture   picRect.Left,   picRect.,   picRect.Right,   picRect.Bottom  
  Picture2.Picture   =   Clipboard.GetData  
  End   Sub  
   
  Private   Sub   Form_Load()  
  Picture1.Appearance   =   0  
  Picture2.Appearance   =   0  
  Command1.Caption   =   "播放"  
  Command2.Caption   =   "暂停"  
  Command3.Caption   =   "抓图"  
  End   Sub  
 

NO.5   作者: goodname008

忘了说了,上面的程序播放的是文件c:\123.avi,具体地改一下路径。  
  在Command3_Click()最后一句加上:  
  SavePicture   Clipboard.GetData(vbCFBitmap),   "c:\123.bmp"  
  可以把截下来的图存到c:\123.bmp。

NO.6   作者: goodname008

to   RyuOut:  
  .mpg的我试了,没问题,RM好像无法用mciSendString播,也就没法测试了,因为其他播放软件的视频是一片黑,按PrintScreen也截不下来。     :(  
  但是截其他软件的视频也像也不常用,因为其他软件大都提供截图功能。

NO.7   作者: zyl910

DirectX是独立于GDI的  
  所以用API是无法办到的  
   
  应该把注意力放在DirectX上

NO.8   作者: pigpag

可以用Windows   Media   Player   6.4版本的控件,并设WindowlessVideo=True,这样播放食品文件时就可以截屏了

NO.9   作者: goodname008

to   楼主:  
  我的WMP版本号是:8.00.00.4487  
  我用PrintScreen键能截屏,最小化恢复不明白?!  
   
  我就是把要播放的文件用mci播并放到PictureBox中,能截屏。

NO.10   作者: hisofty

关于VB下面的一些视频操作的,包括从BMP生成AVI文件,视频图像的捕捉以及DirectX下的图像捕捉等。  
      http://www.shrinkwrapvb.com/  
   
   
      还有:http://www.directx4vb.com  
      看名字就知道干什么的了

NO.11   作者: hisofty

用DirectShow抓取影片帧  
  作者:youken  
   
  很多视频播放软件或视频编辑软件都提供了抓帧的功能,利用这类软件,视频工作者可以很轻松地将一个电影某一时刻的帧抓取出来并保存为图片文件,那么,我们如何自己编程实现这样的功能呢?如果你熟悉MPEG或者AVI等常见视频格式,你可以直接对影片文件进行操作,如果你不知道这些视频格式,而希望使用更简单的方法来抓取影片的帧,微软的DirectShow将会给你极大的惊喜。  
  DirectShow属于DirectX家族,在使用DirectShow开发抓取帧的程序前,你必须要安装DirectX   SDK,这个开发包可以在微软的网站上下载得到,目前最新版本是9.0b;另外,由于DirectX   SDK是用COM的方式发布的,所以对于开发人员而言,他还必须要了解COM的基本原理。如果大家没有使用过COM,可以先从网上找一些COM方面的入门教程看看,VC知识库上就有很多好文章,推荐VC知识库第九期赵湘宁的《COM编程入门》系列。  
   
  一、编程工具的设置:  
   
  先说说我使用的VC   6.0的设置,一般而言,安装完DirectX   9.0b   SDK后,会自动设置好VC,用户无需手动干预,如果编译过程中出现错误,请检查VC是否包含了DirectX   SDK的头文件和库文件,方法是选择菜单“Tools->Options…”,在弹出的Options对话框中选择Directories选项卡,看看Include   files和Library   files中是否包含有DirectX   SDK的Include路径和Lib路径,如果没有,将这两个路径添加上去即可。  
   
  二、主要的实现步骤:  
   
  在实现抓取影片帧的过程中,DirectShow的IMediaDet接口将是主角,这个接口包含了一些方法能够从媒体源文件中提取一些重要信息,比如媒体类型、帧速率甚至是视频流的单个帧。  
  ·注意  
  要正确使用IMediaDet接口,工程中需要包含下列文件:  
  头文件:dshow.h,   qedit.h  
  库文件:strmiids.lib  
  因为使用CComPtr模板来声明接口实例,所以还要在工程中包含atlbase.h头文件。  
  下面我们将一步步利用IMediaDet接口实现抓取影片帧的功能。  
   
  第一步:新建一个基于对话框的应用程序,为应用程序添加两个编辑控件和三个按钮控件,程序界面如图所示:  
   
   
   
  第二步:为对话框类添加一个HRESULT类型的成员函数GrabFramFromMovie,它将实现抓帧功能。在函数体内创建IMediaDet接口实例,创建实例需要调用CoCreateInstance函数,并给函数的第一个参数传入CLSID_MediaDet类标识符。  
   
  第三步:调用IMediaDet::put_Filename方法为接口指定一个媒体文件,该方法只有一个参数,这个参数描述了媒体文件的路径,注意参数类型为BSTR。  
   
  第四步:调用IMediaDet::get_OutputStreams方法以得到影片输出流的数目,一个影片的输出由多个流组成,但是get_OutputStreams方法只关心影片输出的视频流和音频流而自动忽略其它流,所以,如果一个影片输出包含有视频流、音频流和数据流,get_OutputStreams只返回视频流和音频流的数目。  
   
  第五步:调用IMediaDet::put_CurrentStream方法指定一个用于编辑和操作的流,因为我们的目的是要将影片的单个帧保存为图片,这就需要对视频流进行操作,所以要利用put_CurrentStream定位影片文件输出的视频流。  
   
  第六步:调用IMediaDet::get_StreamMediaType方法得到一个VIDEOINFORHEADER结构,这个结构与当前指定的视频流关联。VIDEOINFORHEADER结构中包含有一个BITMAPINFORHEADER结构类型的成员,它描述了视频影像对应位图的尺寸、颜色等有用的信息。  
   
  第七步:调用IMediaDet::WriteBitmapBits方法将影片的帧保存为位图,若想指定保存哪一帧,只需要给第一个参数传递一个合适的时间即可。这里,我传递给第一个参数的时间为0,因此程序将保存影片第一帧的位图。  
   
  下面是GrabFramFromMovie函数的完整代码,其中,变量m_editOpenDir和m_editSaveDir分别指定了影片路径及保存的位图路径,请对照上面的步骤阅读:  
   
   
  HRESULT   CFrameGrabberDlg::GrabFrameFromMovie()  
  {  
  HRESULT   hr;  
  //   定义IMediaDet接口实例  
  CComPtr<   IMediaDet   >   pDet;  
  hr   =   CoCreateInstance(   CLSID_MediaDet,   NULL,   CLSCTX_INPROC_SERVER,    
  IID_IMediaDet,   (void**)   &pDet   );  
  if   (FAILED(hr))  
  return   hr;  
   
  //   将影片文件名转换成BSTR类型  
  CComBSTR   openBSTR(m_editOpenDir);  
  //   设置IMediaDet接口的文件关联  
  hr   =   pDet->put_Filename(openBSTR);  
  if   (FAILED(hr))  
  return   hr;  
   
  //   从影片中检索视频流和音频流  
  long   lStreams;  
          hr   =   pDet->get_OutputStreams(&lStreams);  
          if   (FAILED(hr))  
  return   hr;  
   
  //   取出影片的视频流,因为帧的信息是保存在视频流中的  
  bool   bFound   =   false;  
  for   (int   i=0;   i<lStreams;   i++)  
  {  
  GUID   major_type;  
  hr   =   pDet->put_CurrentStream(i);  
  if   (SUCCEEDED(hr))  
  hr   =   pDet->get_StreamType(&major_type);  
  if   (FAILED(hr))  
  break;  
  if   (major_type   ==   MEDIATYPE_Video)  
  {  
  bFound   =   true;  
  break;  
  }  
  }  
  if   (!bFound)  
  return   VFW_E_INVALIDMEDIATYPE;  
   
  long   width   =   0,   height   =   0;   //   存储位图的宽和高  
          AM_MEDIA_TYPE   mt;  
          hr   =   pDet->get_StreamMediaType(&mt);  
          if   (SUCCEEDED(hr))  
          {  
                  if   ((mt.formattype   ==   FORMAT_VideoInfo)   &&    
                          (mt.cbFormat   >=   sizeof(VIDEOINFOHEADER)))  
                  {  
  //   得到VIDEOINFOHEADER结构指针,VIDEOINFOHEADER结构包含一些与视频  
  //   有关的信息,其中含有BITMAPINFORHEADER结构  
                          VIDEOINFOHEADER   *pVih   =   (VIDEOINFOHEADER*)(mt.pbFormat);  
                          width   =   pVih->bmiHeader.biWidth;  
                          height   =   pVih->bmiHeader.biHeight;  
                  }  
                  else  
                          hr   =   VFW_E_INVALIDMEDIATYPE;  
                  MyFreeMediaType(mt);   //   释放AM_MEDIA_TYPE结构  
          }  
          if   (FAILED(hr))  
  return   hr;  
   
  CComBSTR   saveBSTR(m_editSaveDir);  
  //   将第一帧保存为指定路径的位图文件  
  hr   =   pDet->WriteBitmapBits(0,   width,   height,   saveBSTR);  
  if   (FAILED(hr))  
  return   hr;  
   
  return   S_OK;  
  }  
   
  三、程序运行:  
   
  程序运行后,选择一个影片,然后指定保存路径,点击“抓取”按钮,就可以将影片第一帧保存到指定路径下,我们也可以修改IMediaDet接口的WriteBitmapBits方法中的第一个参数来保存我们指定的帧。源代码的DEBUG文件夹下包含了一个测试影片,供测试使用。该程序在Windows   XP、Visual   C++   6和DirectX   9.0b环境下编译并运行通过。  
   
  http://www.vckbase.com/document/journal/vckbase27/images/FrameGrabber.gif  
  http://www.vckbase.com/code/downcode.asp?id=2221


    摘要: 我的问题是在我的发表文章的jsp文件form中嵌套了一个iframe,iframe调用了upload.jsp文件,upload.jsp中只是一个上传文件的表单.这个表单提交到do_upload.jsp.使图片上传并检查它的后缀名和大小.然后在发表文章的textarea中自动写入img命令.写入的必须是已符合条件并已经上传的img命令. 上传并检查后缀名和大小我已实现,只是不知在发表文章的j......
» 本期热门文章:
· 热门栏目:
» 相关精选文章
» 其它相关:

©2000-2007 All Rights Reserved. 最佳浏览:1024X768 MSIE