我正试图用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)异常)
第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,在调度器线程上调用一个委托来调用WriteableBitmap,类似于"
await Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, () =>
{
// Do stuff on dispatcher thread
});
更新要在调度程序线程上运行的代码后,您将遇到的第二个错误可能是SetSourceAsync调用,而不是WriteableBitmap构造函数。PhotoConfirmationCaptured事件中传递的帧是原始位,而不是编码文件,因此SetSourceAsync不知道该如何处理它。相反,您需要将这些位直接传递到WriteableBitmap的PixelBuffer中。这在PhotoConfirmationCaptured事件及其Frame属性的备注中进行了调用。一定要阅读并理解后者:
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();
}
}