0

I need to output the video from a webcam to file with Aforge.

LocalWebCamsCollection = new FilterInfoCollection(FilterCategory.VideoInputDevice);
LocalWebCam = new VideoCaptureDevice(LocalWebCamsCollection[0].MonikerString);
LocalWebCam.NewFrame += LocalWebCam_NewFrame;
LocalWebCam.Start();

So when I get the frame I write it with:

private void LocalWebCam_NewFrame(object sender, AForge.Video.NewFrameEventArgs eventArgs)
{
    try
    {
        System.Drawing.Image img = (System.Drawing.Bitmap)eventArgs.Frame.Clone();
        MemoryStream ms = new MemoryStream();
        img.Save(ms, ImageFormat.Bmp);
        ms.Seek(0, SeekOrigin.Begin);
        bi = new BitmapImage();
        bi.BeginInit();
        bi.StreamSource = ms;
        bi.EndInit();
        bi.Freeze();

        Application.Current.Dispatcher.Invoke(() =>
        {
            var bmp2 = Helper.BitmapUtilities.BitmapImage2Bitmap(bi);
            FileWriter.WriteVideoFrame(bmp2);
        });     
    }
    catch (Exception ex)
    {
        
    }
}

That works but then if I try to write the timestamp I get the error: "parameter not valid" This is how I change it

System.Drawing.Bitmap bmpOut = null;
Application.Current.Dispatcher.Invoke(() =>
{
    var visual = new DrawingVisual();
    using (DrawingContext drawingContext = visual.RenderOpen())
    {
        drawingContext.DrawImage(bi, new Rect(0, 0, bi.Width, bi.Height));
        drawingContext.DrawText(new FormattedText(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff"), CultureInfo.InvariantCulture, FlowDirection.LeftToRight, new Typeface("Segoe UI"), 32, Brushes.Red), new Point(0, 0));
    }
    var image = new DrawingImage(visual.Drawing);
    #endregion


    img_Webcam.Source = image;

    using (MemoryStream ms = new MemoryStream())
    {
        PngBitmapEncoder encoder = new PngBitmapEncoder();
        encoder.Frames.Add(BitmapFrame.Create(ToBitmapSource(image)));
        encoder.Save(ms);

        using (System.Drawing.Bitmap bmp = new System.Drawing.Bitmap(ms))
        {
            bmpOut = new System.Drawing.Bitmap(bmp);
        }
    }


    FileWriter.WriteVideoFrame(bmpOut);<---here the error
});

Perhaps I have not followed the best strategy so I am open to any other solution: what I need is just to write a timestamp on the bitmap (or bitmapimage) to be written on the file

Thanks for any help

Patrick

--- ADD ---

public static BitmapSource ToBitmapSource(DrawingImage source)
{
    DrawingVisual drawingVisual = new DrawingVisual();
    DrawingContext drawingContext = drawingVisual.RenderOpen();
    drawingContext.DrawImage(source, new Rect(new Point(0, 0), new Size(source.Width, source.Height)));
    drawingContext.Close();

    RenderTargetBitmap bmp = new RenderTargetBitmap((int)source.Width, (int)source.Height, 96, 96, PixelFormats.Pbgra32);
    bmp.Render(drawingVisual);
    return bmp;
}
4
  • It's unclear how your ToBitmapSource method is supposed to convert a DrawingImage into a BitmapSource, as there is no such conversion. You would usually use a RenderTargetBitmap to create a BitmapSource from a Visual. Commented Dec 24, 2021 at 14:45
  • I have added the function. But then again if I have some something wrong I am open to whatever is better to write the timestamp on the bitmapImage bi Commented Dec 24, 2021 at 14:55
  • You should simplify your code. Currently you are creating a DrawingVisual only to use its Drawing for a DrawingImage. Then you create another DrawingVisual that is rendered into a RenderTargetBitmap. Finally you create two Bitmaps from the encoded RenderTargetBitmap, where you need only one. Commented Dec 24, 2021 at 16:06
  • I know... but I couldn't understand how to do it. Could you please post a simplier approach? Commented Dec 24, 2021 at 16:29

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.