2012-10-22 20 views
10

Próbuję napisać aplikację, która może uzyskać dostęp do kamer podłączonych do komputera, nagrać wideo i uzyskać obraz z wideo. Używam bibliotek AForge.NET do uzyskiwania dostępu do kamer: http://www.aforgenet.com/framework/Pobierz obraz z wideo

Nie wiem, jak działa wydarzenie o nazwie AForge.Video.NewFrameEventHandler. W tym kodzie zdarzenie zwraca wartość null do bitmapy zamiast nowej klatki z wideo lub zdarzenie nie jest wywoływane. Chcę, aby klatki z filmu do ramki na zdjęcia za każdym razem, aby zrobić coś jak strumień wideo i po kliknięciu przycisku Stop chcę, aby ostatni obraz pozostaje wyświetlany w polu graficznym. Czy ktoś wie jak? I dlaczego mój kod nie działa?

Kod:

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using AForge.Video.DirectShow; 
using System.Drawing; 
using AForge.Video; 

namespace CameraDevice 
{ 
    public class CameraImaging 
    { 
     // enumerate video devices 
     public FilterInfoCollection videoDevices = new FilterInfoCollection(FilterCategory.VideoInputDevice); 
     //camera 
     public VideoCaptureDevice videoSource; 
     //screen shot 
     public Bitmap bitmap; 
     public CameraImaging() 
     { 
      // create video source 
      VideoCaptureDevice videoSource = new VideoCaptureDevice(videoDevices[0].MonikerString); 
      // set NewFrame event handler 
      videoSource.NewFrame += new NewFrameEventHandler(video_NewFrame); 
     } 
     public void StartVideo(VideoCaptureDevice videoSource) 
     { 
      // start the video source 
      videoSource.Start(); 
      // ... 
     } 
     public void StopVideo(VideoCaptureDevice videoSource) 
     { 
      // stop the video source 
      videoSource.Stop(); 
      // ... 
     } 
     private void video_NewFrame(object sender, NewFrameEventArgs eventArgs) 
     { 
      // get new frame 
      bitmap = eventArgs.Frame; 
      // process the frame 
     } 
    } 
} 

Podobny kod jest tutaj: http://www.aforgenet.com/framework/features/directshow_video.html[ ^]

W Windows Forms uruchomić ten film w wątku, który czyni tę metodę:

private void VideoRecording() 
    { 
     camImg.videoSource.Start(); 

     while (!StopVideo) 
     { 
      pictureBox1.Image = camImg.bitmap; 
      pictureBox1.Invalidate(); 
     } 
     camImg.videoSource.Stop(); 

    } 
+0

AForge.NET wykorzystuje natywny interfejs API DirectShow do uzyskiwania dostępu do sprzętu przechwytywania wideo.Zamiast tego możesz zajrzeć do biblioteki [DirectShow.NET] (http://directshownet.sourceforge.net/), która jest najczęściej używanym "pomostem" pomiędzy aplikacjami .NET i interfejsami API do przechwytywania wideo. –

Odpowiedz

3

Jeśli dobrze pamiętam, bitmapa musi zostać natychmiast skopiowana, ponieważ została nadpisana po zdarzeniu. Używanie odniesienia nie jest tutaj dobre. Spróbuj czegoś takiego:

private void video_NewFrame(object sender, NewFrameEventArgs eventArgs) 
{ 
    // copy the new frame 
    bitmap = new Bitmap(eventArgs.Frame); 
    // process the frame 
} 

lub

private void video_NewFrame(object sender, NewFrameEventArgs eventArgs) 
{ 
    // clone new frame 
    bitmap = eventArgs.Frame.Clone(); 
    // process the frame 
} 

Również nie należy używać dodatkowego wątku dla tego AForge już robi.

  1. Zaproszenie Start (na przykład w przypadku obciążenia, lub po naciśnięciu przycisku)
  2. obsługi zdarzeń ramka

    private void VideoStream_NewFrame (object sender, EventArgs) AForge.Video.NewFrameEventArgs { Bitmap newFrame = new Bitmap (eventArgs.Frame); pictureBox1.Image = newFrame; }

  3. połączeń Stop (zamknięcie zdarzenia lub przycisku)

Jeśli napotkasz problemów z WinForm steruje np etykieta, którą musisz wiedzieć, że te formanty zostały utworzone w innym wątku i musisz użyć Invoke. Np:

label_ms.Invoke((MethodInvoker)(() => label_ms.Text = msTimeSpan.TotalMilliseconds.ToString())); 

Najprościej jest sprawdzić to AForge próbkę, która pochodzi z ramami: http://aforge.googlecode.com/svn/trunk/Samples/Video/Player/

1

używam biblioteki wideo Aforge z moim Foscams, i to działa bardzo dobrze. Oto mój kod dla obsługi zdarzenia.