Writeablebitmap构造函数崩溃

时间:2014-10-12 20:10:27

标签: c# windows-phone-8.1 ocr

我正在尝试用Windows Phone 8.1做一些ocr:https://blogs.windows.com/buildingapps/2014/09/18/microsoft-ocr-library-for-windows-runtime/

private async void camera_PhotoConfirmationCaptured(MediaCapture sender, PhotoConfirmationCapturedEventArgs e)
{
    try
    {
        WriteableBitmap bitmap = new WriteableBitmap((int)e.Frame.Width, (int)e.Frame.Height); //crash here
        await bitmap.SetSourceAsync(e.Frame);

        OcrResult result = await ocr.RecognizeAsync(e.Frame.Height, e.Frame.Width, bitmap.PixelBuffer.ToArray());

        foreach (var line in result.Lines)
        {

        }
    }

    catch(Exception ex)
    {

    }
}

private async void takePictureButton_Click(object sender, RoutedEventArgs e)
{
    await camera.CapturePhotoToStreamAsync(Windows.Media.MediaProperties.ImageEncodingProperties.CreatePng(), imageStream);
}

我一直在WriteableBitmap构造函数上崩溃,我不知道如何解决它。 RecognizeAsync必须采用可写位图。这是例外:

该应用程序调用了一个为不同线程编组的接口。 (来自HRESULT的异常:0x8001010E(RPC_E_WRONG_THREAD))

EDIT1:

我尝试了这段代码并在此行中获得了一个例外:

        WriteableBitmap bitmap = null;

        await Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, async () =>
        {
            bitmap = new WriteableBitmap((int)e.Frame.Width, (int)e.Frame.Height); //crash here again
            await bitmap.SetSourceAsync(e.Frame);

            OcrResult result = await ocr.RecognizeAsync(e.Frame.Height, e.Frame.Width, bitmap.PixelBuffer.ToArray());

            foreach (var line in result.Lines)
            {

            }
        });

“灾难性故障(HRESULT异常:0x8000FFFF(E_UNEXPECTED))”

您认为这会导致什么?

1 个答案:

答案 0 :(得分:3)

这里有几个问题。第一个错误(RPC_E_WRONG THREAD)是因为UI对象需要从调度程序(也称为UI)线程调用,而不是从工作线程调用。您可以调用Dispatcher.RunAsync以在调度程序线程上调用一个委托调用WriteableBitmap,类似于"

await Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, () =>
    {
        // Do stuff on dispatcher thread
    });

更新代码以在调度程序线程上运行后,您获得的第二个错误可能是在SetSourceAsync调用而不是WriteableBitmap构造函数上。在PhotoConfirmationCaptured事件中传递的帧是原始位,而不是编码文件,因此SetSourceAsync不知道如何处理它。相反,您需要将位直接传递到WriteableBitmap的PixelBuffer中。这在PhotoConfirmationCaptured事件及其Frame属性的备注中调用。绝对阅读并理解the latter

   void PhotoConfirmationCaptured(MediaCapture sender, PhotoConfirmationCapturedEventArgs args)
   {
   using (ManualResetEventSlim evt = new ManualResetEventSlim(false))
   {
       Dispatcher.RunAsync(CoreDispatcherPriority.Normal, async () =>
       {
           try
           {
               WriteableBitmap bmp = new WriteableBitmap(unchecked((int)args.Frame.Width), unchecked((int)args.Frame.Height));
               using (var istream = args.Frame.AsStream())
               using (var ostream = bmp.PixelBuffer.AsStream())
               {
                   await istream.CopyStreamToAsync(ostream);
               }
           }
           finally
           {
               evt.Set();
           }

       });

       evt.Wait();
   }

}