secile / UsbCamera

C# source code for using usb camera and web camera in WinForms/WPF. With only single CSharp source code. No external library required.
MIT License
179 stars 55 forks source link

How can I get the datas of every frame? #20

Closed hellottyp closed 1 year ago

secile commented 1 year ago

Hello. You have to modify UsbCamera.cs a little. Try these changes below and let me know it works fine or not.

Step1. Add this block around line 80.

public Action<Bitmap> BitmapCaptured
{
    get { return CaptureGrabberCallback.Buffered; }
    set { CaptureGrabberCallback.Buffered = value; }
}
private SampleGrabberCallback CaptureGrabberCallback;

Step2. Replace this block from

private Func<Bitmap> GetBitmapFromSampleGrabberCallback(DirectShow.ISampleGrabber i_grabber, int width, int height, int stride)
{
    var sampler = new SampleGrabberCallback(width, height, stride);
    i_grabber.SetCallback(sampler, 1); // WhichMethodToCallback = BufferCB
    return () => sampler.GetBitmap();
}

to

private Func<Bitmap> GetBitmapFromSampleGrabberCallback(DirectShow.ISampleGrabber i_grabber, int width, int height, int stride)
{
    CaptureGrabberCallback = new SampleGrabberCallback(width, height, stride);
    i_grabber.SetCallback(CaptureGrabberCallback, 1); // WhichMethodToCallback = BufferCB
    return () => CaptureGrabberCallback.GetBitmap();
}

Step3. subscribe BitmapCaptured.

camera.BitmapCaptured += (bmp) =>
{
    // called here every frame captured.
};
hellottyp commented 1 year ago

good,thanks!it works very well.

hellottyp commented 1 year ago

it works,but it isn't thread-safe.

secile commented 1 year ago

Could you show me the code that produce the problem?

hellottyp commented 1 year ago

like this:

 camera.BitmapCaptured += (bmp) =>
  {
      this.textBox1.Text = "hello";
      this.BackgroundImage = bmp;
  };

You're better off implementing it with events

secile commented 1 year ago

Are you saying that the line below cause InvalidOperationException? (Cross-thread operation not valid.)

this.textBox1.Text = "hello";

If so, it is your responsibility to call cross-thread control in a thread-safe way.

textBox1.Invoke((Action)(() =>
{
    this.textBox1.Text = "hello";
}));
hellottyp commented 1 year ago

I did it.And it can work.But I have many controls to process.So I will do more work.It's not just convenient.

hellottyp commented 1 year ago

I use delegates to handle those controls, so I do a lot of things. Using Invoke is much easier.thanks!

secile commented 1 year ago

Thank you for your response.