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

Add an IsReady method to see if we can get the image? #38

Open 1234567Yang opened 2 months ago

1234567Yang commented 2 months ago

For example: image

secile commented 2 months ago

Hello. To implement your request, you must be changed 3 parts.

(1) about line 560. add IsReady property.

private class SampleGrabberCallback : DirectShow.ISampleGrabberCB
{
    private byte[] Buffer;
    private object BufferLock = new object();

    public bool IsReady { get { return Buffer != null; } } <- Add this line.

(2) about line 85. add IsReady property.

class UsbCamera
{
    ....
    private Action Releasing;
    private Action Released;

    public bool IsReady { get { return Streams[StreamType.Capture].IsReady; } }  <- Add this line.

(3) about line 250.

change code from

GetBitmap = GetBitmapFromSampleGrabberCallback(sample.Grabber, sample.Width, sample.Height, sample.Stride);
Func<Bitmap> GetBitmapFromSampleGrabberCallback(DirectShow.ISampleGrabber grabber, int width, int height, int stride)
{
    var sampler = new SampleGrabberCallback(grabber, width, height, stride, false);
    return () => sampler.GetBitmap();
}

to

GetBitmap = GetBitmapFromSampleGrabberCallback(sample.Grabber, sample.Width, sample.Height, sample.Stride);
Func<Bitmap> GetBitmapFromSampleGrabberCallback(DirectShow.ISampleGrabber grabber, int width, int height, int stride)
{
    Streams[StreamType.Capture] = new SampleGrabberCallback(grabber, width, height, stride, false);
    return () => Streams[StreamType.Capture].GetBitmap();
}

Then you can use IsReady property like this.

var sw = System.Diagnostics.Stopwatch.StartNew();
while(camera.IsReady == false)
{
    System.Threading.Thread.Sleep(10);
}
Console.WriteLine("sw:{0}", sw.ElapsedMilliseconds);

Is this meets your request? I'll attach modified UsbCamera.cs. Could you try this? UsbCamera_add_IsReady.zip

1234567Yang commented 2 months ago

Hi, thank you for replying, I will try it after I get home today.

1234567Yang commented 2 months ago

Yes, It works! That will make people (at least myself) a lot easier to get the photo as soon as possible. Thank you very much!

        private void Form1_Load(object sender, EventArgs e)
        {
            string[] devices = UsbCamera.FindDevices();
            if (devices.Length == 0) return; // no camera.
            var cameraIndex = 0;
            var formats = UsbCamera.GetVideoFormat(cameraIndex);
            foreach (var item in formats) Console.WriteLine(item);
            var format = formats[0];
            var camera = new UsbCamera(cameraIndex, format);
            camera.Start();

            Stopwatch stopwatch = Stopwatch.StartNew();

            while(!camera.IsReady) Thread.Sleep(50);

            stopwatch.Stop();
            Console.WriteLine(stopwatch.ElapsedMilliseconds);

            var bmp = camera.GetBitmap();
            camera.Stop();
            camera.Release();
            this.pictureBox1.Image = bmp;

        }