c# - 可写位图构造函数崩溃

标签 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 必须采用可写位图。这是异常(exception)情况:

应用程序调用了为不同线程编码的接口(interface)。 (HRESULT 异常:0x8001010E (RPC_E_WRONG_THREAD))

编辑1:

我尝试了这段代码,并在这一行遇到了异常:

        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))”

您认为是什么原因造成的?

最佳答案

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

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

更新代码以在调度程序线程上运行后遇到的第二个错误可能是在 SetSourceAsync 调用上,而不是在 WriteableBitmap 构造函数上。 PhotoConfirmationCaptured 事件中传递的 Frame 是原始位,而不是编码文件,因此 SetSourceAsync 不知道如何处理它。相反,您需要将这些位直接传递到 WriteableBitmap 的 PixelBuffer 中。这在PhotoConfirmationCaptured的备注中被提及。事件及其Frame属性(property)。一定要阅读并理解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();
   }

}

关于c# - 可写位图构造函数崩溃,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26329484/

相关文章:

python - 修复 "ModuleNotFoundError: No module named ' fsns'"in google colab for Attention ocr

c++ - 如何使用 C++ 在 tesseract 中设置和获取变量

c# - 如何枚举 PropertyGrid 项?

c# - 在 Caliburn Micro 的操作中将枚举作为参数传递

c# - ServiceStack请求参数还是 session 变量?

windows-runtime - Windows Phone 8.1 运行时中缺少 DeviceFirmwareVersion、OSVersion、DeviceStatus

c# - 在default.aspx中调用jquery

c# - Windows Phone 模拟器未启动

c# - 交互触发 wp8.1(silverlight) 时的 xaml 解析错误

php - PHP图像识别