简体   繁体   English

如何将ISampleGrabber :: BufferCB的缓冲区转换为位图

[英]How to convert ISampleGrabber::BufferCB's buffer to a bitmap

I am trying to use the ISampleGrabberCB::BufferCB to convert the current frame to bitmap using the following code: 我正在尝试使用ISampleGrabberCB::BufferCB通过以下代码将当前帧转换为位图:

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. 一旦运行了此代码,我将得到一个显示“ Works”的消息框,这意味着必须调用BufferCB ,但是不会使用当前图像更新我的图片框。

Is the BufferCB not called after every new frame? 是否在每个新帧之后都不调用BufferCB If so why do I not recieve the 'Works' message box? 如果是这样,为什么我没有收到“ Works”消息框?

Finally is it possible to convert every new frame into a bitmap (this is used for later processing) using BufferCB and if so how? 最后,可以使用BufferCB将每个新帧转换成一个位图(用于以后的处理),如果可以,怎么办?

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 我还需要按一下按钮才能运行BufferCB

Thanks for reading. 谢谢阅读。

BufferCB is called for every new frame that has been captured by the camera. 相机已捕获的每个新帧都会调用BufferCB You don't see the message box, because the method is called from another thread (not the ui thread). 您不会看到消息框,因为该方法是从另一个线程(不是ui线程)调用的。 See this question for details. 有关详细信息,请参见此问题

In my code I used AutoResetEvent for capturing a frame: 在我的代码中,我使用AutoResetEvent捕获帧:

#region samplegrabber
/// <summary>
///   buffer callback, COULD BE FROM FOREIGN THREAD.
/// </summary>
int ISampleGrabberCB.BufferCB (double sampleTime,
                              IntPtr pBuffer,
                              int bufferLen)
{
  if (_sampleRequest)
  {
    _sampleRequest = false;

    if (bufferLen > _bufferSize)
      throw new Exception ("buffer is wrong size");

    Win32.CopyMemory (_buffer, pBuffer, _bufferSize);

    // Picture is ready.
    _resetEvent.Set ();
  }
  else
    _dropped++;
  return 0;
}

The image can then be decoded from the IntPtr with another function: 然后可以使用另一个函数从IntPtr解码图像:

public Image Decode (IntPtr data)
{
  var bitmap = new Bitmap (_width, _height, _stride, PixelFormat.Format24bppRgb, data);

  bitmap.RotateFlip (RotateFlipType.RotateNoneFlipY);

  return bitmap;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM