2

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;
    }

ただし、これは機能していないようです。

さらに、次のコードを実行するボタンを押すと、この関数が呼び出されるようです:

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;

    }

このコードが実行されると、'Works' を示すメッセージ ボックスが表示されます。つまり、BufferCB呼び出される必要があることを意味しますが、画像ボックスは現在の画像で更新されません。

BufferCBすべての新しいフレームの後に呼び出されませんか? その場合、'Works' メッセージ ボックスが表示されないのはなぜですか?

最後に、すべての新しいフレームをビットマップに変換することは可能ですか (これは後の処理に使用されます) BufferCB

編集されたコード:

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;
    }

ボタンコード:

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;

    }

また、実行するにはボタンを押す必要がありますBufferCB

読んでくれてありがとう。

4

1 に答える 1

1

BufferCBカメラによってキャプチャされたすべての新しいフレームに対して呼び出されます。メソッドが (UI スレッドではなく) 別のスレッドから呼び出されるため、メッセージ ボックスは表示されません。詳細については、この質問を参照してください。

私のコードでは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;
}

IntPtr次に、別の関数を使用してから画像をデコードできます。

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

  bitmap.RotateFlip (RotateFlipType.RotateNoneFlipY);

  return bitmap;
}
于 2013-10-27T19:28:46.550 に答える