我正在尝试用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))”
您认为这会导致什么?
答案 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();
}
}