2017-10-30 31 views
0

このコードでは、私のハードディスクからビデオファイルを再生し、ビデオをpictureBox1に表示することができます。しかし、私はどのようにハードディスクのイメージファイルにビデオのすべてのフレームを保存することができますか?ビデオを再生しながら、または再生せずに、何とかフレームを抽出して保存する必要があります。directshowlib-2005を使用してビデオからフレームを抽出するにはどうすればよいですか?

これは、これまで私のためのコードです:

namespace WindowsFormsApplication1 
{ 
    public partial class Form1 : Form 
    { 

     IGraphBuilder m_graphBuilder = null; 
     IMediaControl m_mediaCtrl = null; 
     IMediaEventEx m_mediaEvt = null; 
     IMediaPosition m_mediaPos = null; 
     IMediaSeeking m_mediaSeeking = null; 

     public Form1() 
     { 
      InitializeComponent(); 
     } 

     void InitInterfaces() 
     { 
      try 
      { 
       m_graphBuilder = (IGraphBuilder)new FilterGraph(); 
       m_mediaCtrl = (IMediaControl)m_graphBuilder; 
       m_mediaEvt = (IMediaEventEx)m_graphBuilder; 
       m_mediaPos = (IMediaPosition)m_graphBuilder; 
       m_mediaSeeking = (IMediaSeeking)m_graphBuilder; 
      } 
      catch (Exception) 
      { 
       MessageBox.Show("Couldn't start directshow graph"); 
      } 
     } 


     void CloseInterfaces() 
     { 
      if (m_mediaCtrl != null) 
      { 
       m_mediaCtrl.StopWhenReady(); 
      } 
      m_mediaCtrl = null; 
      m_mediaEvt = null; 
      m_mediaPos = null; 

      m_mediaSeeking = null; 

      if (m_graphBuilder != null) 
       Marshal.ReleaseComObject(this.m_graphBuilder); 
      m_graphBuilder = null; 
     } 


     private void Form1_Load(object sender, EventArgs e) 
     { 

     } 

     private void SetuupVideoRenderer() 
     { 
      IBaseFilter vmrFilter = null; 

      vmrFilter = (IBaseFilter)new VideoMixingRenderer(); 
      m_graphBuilder.AddFilter(vmrFilter, "Video Renderer"); 

      IVMRFilterConfig FilterConfig = (IVMRFilterConfig)vmrFilter; 
      FilterConfig.SetRenderingMode(VMRMode.Windowless); 

      IVMRWindowlessControl windowlessCtrl = (IVMRWindowlessControl)vmrFilter; 
      windowlessCtrl.SetVideoClippingWindow(this.pictureBox1.Handle); 
      windowlessCtrl.SetVideoPosition(null, DsRect.FromRectangle(pictureBox1.ClientRectangle)); 
      windowlessCtrl.SetAspectRatioMode(VMRAspectRatioMode.LetterBox); 

     } 
     private void buttonLoad_Click(object sender, EventArgs e) 
     { 
      openFileDialog1.Filter = "All Files (*.*)|*.*|mp4 (*.mp4)|*.mp4|mov (*.mov)|*.mov||"; 
      if (openFileDialog1.ShowDialog() == DialogResult.OK) 
      { 
       CloseInterfaces(); 
       InitInterfaces(); 

       SetuupVideoRenderer(); 
       m_graphBuilder.RenderFile(openFileDialog1.FileName, null); 

       textBoxDur.Text = (getDuration() * 0.0000001).ToString(); 
       m_mediaCtrl.Run(); 

       timer1.Enabled = true; 

      } 
     } 

     private void GetPosition(out long CurrentPos,out long StopPos) 
     { 

      m_mediaSeeking.GetPositions(out CurrentPos, out StopPos); 

     } 
     private long getDuration() 
     { 
      long duration; 
      m_mediaSeeking.GetDuration(out duration); 

      return duration; 

     } 

     private void SetPos(double fPos) 
     { 
      DsLong startPosition = (DsLong)(10000000 * fPos); 

      m_mediaSeeking.SetPositions(startPosition, AMSeekingSeekingFlags.AbsolutePositioning, null, AMSeekingSeekingFlags.NoPositioning); 


     } 
     private void buttonPause_Click(object sender, EventArgs e) 
     { 
      m_mediaCtrl.Pause(); 
     } 

     private void buttonPlay_Click(object sender, EventArgs e) 
     { 
      m_mediaCtrl.Run(); 

     } 
     private void OnVideoCompleted() 
     { 
      MessageBox.Show("Video Playback Completed"); 
     } 
     private void timer1_Tick(object sender, EventArgs e) 
     { 
      long iCurPos, iStopPos; 

      GetPosition(out iCurPos, out iStopPos); 

      if (iCurPos >= iStopPos) 
      { 
       timer1.Enabled = false; 
       OnVideoCompleted(); 
       return; 
      } 
      textBoxCurPos.Text = (iCurPos * 0.0000001).ToString(); 


     } 

     private void buttonGo_Click(object sender, EventArgs e) 
     { 
      SetPos(Convert.ToDouble(textBoxNewPos.Text)); 
      timer1.Enabled = true; 
     } 
    } 
} 
+0

あなたがこれまでにウル自身で試してみましたか? –

+0

@ L.Guthardt私はdirectshowlibを初めて使っています。これまでは、m_mediaSeekingやm_mediaPosなどの変数すべてをチェックしようとしましたが、情報だけを取得することはできます。私もpictureBox1.Image.Saveを作成しようとしました....タイマーの内部または再生を開始するが、それを再生し、画像box1から画像を保存するロジックではないようです。 1時間のビデオがあれば、すべてのフレームを保存するのに多くの時間がかかります。 –

+0

@ L.Guthardtどこから始めてもわからない。可能であれば、私はどのように起動するのか分かりません。 –

答えて

1

私は、これはあなたが探しているものexcatlyだと思う: extract frames of a video

このSO questionでも同様に見てみると、これに提供されたリンクウェブページ。

あなたのアプリに余分な30 + Mbが追加されていない場合、そのAlredyには最も一般的なコーデックがいくつか含まれているため、FFMPEGを使用するのが最も簡単な方法です。ラッパーに関しては、私は過去にAForgeラッパーを使用していましたが、本当にそれが好きでした。ここではそのドキュメントからの例です:

// create instance of video reader 
VideoFileReader reader = new VideoFileReader(); 

// open video file 
reader.Open("test.avi"); 

// read 100 video frames out of it 
for (int i = 0; i < 100; i++) 
{ 
    Bitmap videoFrame = reader.ReadVideoFrame(); 

    videoFrame.Save(i + ".bmp") 

    // dispose the frame when it is no longer required 
    videoFrame.Dispose(); 
} 

reader.Close(); 
関連する問題