Получите поток веб-камеры, используя Aforge.NET в C # и WPF - PullRequest
10 голосов
/ 26 мая 2011

Я хочу захватить канал веб-камеры, используя мою камеру.Для этого я использую 2 ссылки: AForge.Video.dll и AForge.Video.DirectShow.dll.

Вот фрагмент, который я нашел:

public FilterInfoCollection CamsCollection;
public VideoCaptureDevice Cam = null;

void Cam_NewFrame(object sender, NewFrameEventArgs eventArgs)
{   
  frameholder.Source = (Bitmap)eventArgs.Frame.Clone(); 
  /* ^
   * Here it cannot convert implicitly from System.Drawing.Bitmap to
   * System.Windows.Media.ImageSource
   */

}

private void startcam_Click(object sender, RoutedEventArgs e)
{
  CamsCollection = new FilterInfoCollection(FilterCategory.VideoInputDevice);

  Cam = new VideoCaptureDevice(CamsCollection[1].MonikerString);
  Cam.NewFrame += new NewFrameEventHandler(Cam_NewFrame);
  Cam.Start();
}

private void stopcam_Click(object sender, RoutedEventArgs e)
{
  Cam.Stop();
}

}

Они используют PictureBox для отображения кадров.Поскольку я работаю в WPF, я использовал this

Чтобы подвести итог, вот как выглядит мой код в настоящее время.

public FilterInfoCollection CamsCollection;
public VideoCaptureDevice Cam = null;


void Cam_NewFrame(object sender, NewFrameEventArgs eventArgs)
{

    System.Drawing.Image imgforms = (Bitmap)eventArgs.Frame.Clone();


    BitmapImage bi = new BitmapImage();
    bi.BeginInit ();

    MemoryStream ms = new MemoryStream ();

    imgforms.Save(ms, ImageFormat.Bmp);

    ms.Seek(0, SeekOrigin.Begin);
    bi.StreamSource  = ms;
    frameholder.Source = bi; 
   /* ^ runtime error here because `bi` is occupied by another thread.
    */
    bi.EndInit();
}

private void startcam_Click(object sender, RoutedEventArgs e)
{

    CamsCollection = new FilterInfoCollection(FilterCategory.VideoInputDevice);

    Cam = new VideoCaptureDevice(CamsCollection[1].MonikerString);
    Cam.NewFrame += new NewFrameEventHandler(Cam_NewFrame);
    Cam.Start();
}

private void stopcam_Click(object sender, RoutedEventArgs e)
{
    Cam.Stop();
}

Ответы [ 2 ]

7 голосов
/ 30 мая 2011

Edit1: для подробного объяснения посмотрите мой blogpost на ту же тему.


Я исправил ошибку, используя класс Dispatcher в качествеmutex:

void Cam_NewFrame(object sender, NewFrameEventArgs eventArgs)
    {

        System.Drawing.Image imgforms = (Bitmap)eventArgs.Frame.Clone(); 

        BitmapImage bi = new BitmapImage(); 
        bi.BeginInit(); 

        MemoryStream ms = new MemoryStream(); 
        imgforms.Save(ms, ImageFormat.Bmp); 
        ms.Seek(0, SeekOrigin.Begin); 

        bi.StreamSource = ms; 
        bi.EndInit();

        //Using the freeze function to avoid cross thread operations 
        bi.Freeze();

        //Calling the UI thread using the Dispatcher to update the 'Image' WPF control         
        Dispatcher.BeginInvoke(new ThreadStart(delegate
        {
            frameholder.Source = bi; /*frameholder is the name of the 'Image' WPF control*/
        }));     

    }

Теперь он работает как положено, и я получаю хорошую производительность без падения частоты кадров.

1 голос
/ 29 мая 2011

Если вы хотите поддерживать Silverlight, будь то веб или автономно, или WP7, не стоит начинать с WPF, так как многие функции из WPF отсутствуют в Silverlight.

Вот учебник по Silverlight 4+:

http://www.silverlightshow.net/items/Capturing-the-Webcam-in-Silverlight-4.aspx

...