How to convert ISampleGrabber::BufferCB's buffer to a bitmap

Posted by user2509919 on Stack Overflow See other posts from Stack Overflow or by user2509919
Published on 2013-10-27T19:19:17Z Indexed on 2013/10/27 21:54 UTC
Read the original article Hit count: 1428

I am trying to use the ISampleGrabberCB::BufferCB to convert the current frame to bitmap using the following code:

int ISampleGrabberCB.BufferCB(double sampleTime, IntPtr buffer, int bufferLength)
    {
        try
        {

            Form1 form1 = new Form1("", "", "");
            if (pictureReady == null)
            {
                Debug.Assert(bufferLength == Math.Abs(pitch) * videoHeight, "Wrong Buffer Length");
            }

            Debug.Assert(imageBuffer != IntPtr.Zero, "Remove Buffer");

            Bitmap bitmapOfCurrentFrame = new Bitmap(width, height, capturePitch, PixelFormat.Format24bppRgb, buffer);
            MessageBox.Show("Works");
            form1.changepicturebox3(bitmapOfCurrentFrame);

            pictureReady.Set();
        }
        catch (Exception ex)
        {
            MessageBox.Show(ex.ToString());
        }

        return 0;
    }

However this does not seem to be working.

Additionally it seems to call this function when i press a button which runs the following code:

public IntPtr getFrame()
    {
        int hr;
        try
        {
            pictureReady.Reset();
        }
        catch (Exception ex)
        {
            MessageBox.Show(ex.ToString());
        }
        imageBuffer = Marshal.AllocCoTaskMem(Math.Abs(pitch) * videoHeight);

        try
        {
            gotFrame = true;

            if (videoControl != null)
            {
                hr = videoControl.SetMode(stillPin, VideoControlFlags.Trigger);
                DsError.ThrowExceptionForHR(hr);
            }

            if (!pictureReady.WaitOne(9000, false))
            {
                throw new Exception("Timeout waiting to get picture");
            }

        }
        catch
        {
            Marshal.FreeCoTaskMem(imageBuffer);
            imageBuffer = IntPtr.Zero;
        }

        return imageBuffer;

    }

Once this code is ran I get a message box which shows 'Works' thus meaning my BufferCB must of been called however does not update my picture box with the current image.

Is the BufferCB not called after every new frame? If so why do I not recieve the 'Works' message box?

Finally is it possible to convert every new frame into a bitmap (this is used for later processing) using BufferCB and if so how?

Edited code:

int ISampleGrabberCB.BufferCB(double sampleTime, IntPtr buffer, int bufferLength)
    {           

            Debug.Assert(bufferLength == Math.Abs(pitch) * videoHeight, "Wrong Buffer Length"); 
            Debug.Assert(imageBuffer != IntPtr.Zero, "Remove Buffer");
            CopyMemory(imageBuffer, buffer, bufferLength);
            Decode(buffer);   


        return 0;
    }

public Image Decode(IntPtr imageData)
    {
        var bitmap = new Bitmap(width, height, pitch, PixelFormat.Format24bppRgb, imageBuffer);
        bitmap.RotateFlip(RotateFlipType.RotateNoneFlipY);
        Form1 form1 = new Form1("", "", "");
        form1.changepicturebox3(bitmap);
        bitmap.Save("C:\\Users\\...\\Desktop\\A2 Project\\barcode.jpg");
        return bitmap;
    }

Button code:

public void getFrameFromWebcam()
{
   if (iPtr != IntPtr.Zero)
   {
       Marshal.FreeCoTaskMem(iPtr);
       iPtr = IntPtr.Zero;
   }

        //Get Image
        iPtr = sampleGrabberCallBack.getFrame();
        Bitmap bitmapOfFrame = new Bitmap(sampleGrabberCallBack.width, sampleGrabberCallBack.height, sampleGrabberCallBack.capturePitch, PixelFormat.Format24bppRgb, iPtr);
        bitmapOfFrame.RotateFlip(RotateFlipType.RotateNoneFlipY);
        barcodeReader(bitmapOfFrame);
}

public IntPtr getFrame()
    {
        int hr;

        try
        {
            pictureReady.Reset();
        }
        catch (Exception ex)
        {
            MessageBox.Show(ex.ToString());
        }
        imageBuffer = Marshal.AllocCoTaskMem(Math.Abs(pitch) * videoHeight);

        try
        {
            gotFrame = true;

            if (videoControl != null)
            {
                hr = videoControl.SetMode(stillPin, VideoControlFlags.Trigger);
                DsError.ThrowExceptionForHR(hr);
            }

            if (!pictureReady.WaitOne(9000, false))
            {
                throw new Exception("Timeout waiting to get picture");
            }

        }
        catch
        {
            Marshal.FreeCoTaskMem(imageBuffer);
            imageBuffer = IntPtr.Zero;
        }

        return imageBuffer;

    }

I also still need to press the button to run the BufferCB

Thanks for reading.

© Stack Overflow or respective owner

Related posts about c#

Related posts about image-processing