Microsoft LifeCam ESCAPI - 在ui thead工作,而不是在任务内部工作

时间:2017-02-17 20:47:35

标签: c# c++-cli webcam

我在尝试构建一个窗口时遇到了问题,我可以在其中显示来自我的microsoft lifecam的Feed。基本上我可以拍摄一个或多个屏幕截图,但如果我把代码放在一个线程中(这样我就可以实时显示feed而不会阻止ui)API失败,告诉我没有设备找到。这是代码:

C ++ CLI:

EasyPicture::EasyPicture()
{
    int devices = setupESCAPI(); //returns 1 if run synchronously, 0 otherwise
    _apiInitialized = devices > 0;
    std::cout << (_apiInitialized ? "Escapi initialized successfully!\n" : "Failed to init escapi.\n");
    _capture = new struct SimpleCapParams();
}

bool EasyPicture::GetFrame(void* buffer, int width, int height)
{
    if (!_apiInitialized || buffer == nullptr || width == 0 || height == 0)
        return false;
    pin_ptr<int> buffPtr = reinterpret_cast<int*>(buffer);

    _capture->mTargetBuf = buffPtr;

    _captureInitialized = _capture->mWidth == width && _capture->mHeight == height;

    _capture->mWidth = width;
    _capture->mHeight = height;

    if (!_captureInitialized)
    {
        //works if run synchronously, otherwise returns 0 (failed)
        if (initCapture(0, _capture) == 0) //Maybe the device is already in use
        {
            if (Disconnect()) // try to disconnect it
            {
                if (initCapture(0, _capture) == 0)
                {
                    _captureInitialized = false;
                    return false;
                }
                _captureInitialized = true;
            }
            else
            {
                _captureInitialized = false;
                return false;
            }               
        }
    }

    doCapture(0);

    while (isCaptureDone(0) == 0)
    {
        /* Wait until capture is done. */
    }

    return true;
}

C#代码

private void UserControl_Loaded(object sender, RoutedEventArgs e)
    {
        _cts = new CancellationTokenSource();
        _frameLoop = new Task(() =>
        {
            Frame = new Bitmap(_width, _height, System.Drawing.Imaging.PixelFormat.Format32bppArgb);
            var BoundsRect = new System.Drawing.Rectangle(0, 0, _width, _height);
            BitmapData bmpData = Frame.LockBits(BoundsRect, ImageLockMode.WriteOnly, Frame.PixelFormat);
            int counter = 0;
            while(!_cts.IsCancellationRequested)
            {
                unsafe
                {
                    if (!_picHelper.GetFrame((void*)bmpData.Scan0, _width, _height))
                    {

                    }
                    else
                    {
                        Frame.Save("Test_" + counter + ".bmp"); //For now i just save the frame, i have yet to figure out how to put the bitmap in xaml without copying it...
                      /*  Image = System.Windows.Interop.Imaging.CreateBitmapSourceFromHBitmap(
                           Frame.GetHbitmap(),
                           IntPtr.Zero,
                           System.Windows.Int32Rect.Empty,
                           BitmapSizeOptions.FromWidthAndHeight(_width, _height));*/
                    }
                }
                Thread.Sleep(500);
            }
            Frame.UnlockBits(bmpData);
        },_cts.Token);
        _frameLoop.RunSynchronously();// Start(); Works only with RunSynchronously, but blocks ui of course
    }

有人能指出我正确的方向吗?

1 个答案:

答案 0 :(得分:0)

让编译器为您管理任务。完全摆脱匿名委托,只需将循环放在事件处理程序中,并使用await Task.Delay代替Thread.Sleep