static async Task <string> SubmitBitmapToCloudGetResultLocationAsync( string cloudEndpoint, string cloudApiKey, DeviceOcrResult deviceOcrResult) { string resultLocation = null; // First, encode the software bitmap as a Jpeg... using (var memoryStream = new InMemoryRandomAccessStream()) { var encoder = await BitmapEncoder.CreateAsync(BitmapEncoder.JpegEncoderId, memoryStream); encoder.SetSoftwareBitmap(deviceOcrResult.BestOcrSoftwareBitmap); await encoder.FlushAsync(); memoryStream.Seek(0); // Now, send it off to the computer vision API. using (var httpClient = new HttpClient()) using (var httpContent = new HttpStreamContent(memoryStream)) { httpContent.Headers["Content-Type"] = "application/octet-stream"; httpClient.DefaultRequestHeaders[API_SUBSCRIPTION_KEY_HEADER] = cloudApiKey; using (var response = await httpClient.PostAsync(new Uri(cloudEndpoint), httpContent)) { if (response.IsSuccessStatusCode) { resultLocation = response.Headers["Operation-Location"]; } } } } return(resultLocation); }
public async Task <GeneralOcrResult> MatchOnCloudAsync( string cloudEndpoint, string cloudApiKey, DeviceOcrResult deviceOcrResult, TimeSpan timeBetweenCalls, TimeSpan timeout) { GeneralOcrResult ocrResult = new GeneralOcrResult() { ResultType = OcrMatchResult.CloudCallFailed }; if (deviceOcrResult.ResultType != OcrMatchResult.TimedOutCloudCallAvailable) { throw new InvalidOperationException(); } var resultLocation = await SubmitBitmapToCloudGetResultLocationAsync( cloudEndpoint, cloudApiKey, deviceOcrResult); if (!string.IsNullOrEmpty(resultLocation)) { ocrResult = await PollCloudResultLocation(resultLocation, cloudApiKey, timeBetweenCalls, timeout); } return(ocrResult); }
async Task OcrProcessFrameAsync( MediaFrameReader reader, OcrEngine ocrEngine, DeviceOcrResult ocrDeviceResult) { using (var frame = reader.TryAcquireLatestFrame()) { if (frame?.VideoMediaFrame != null) { using (var bitmap = frame.VideoMediaFrame.SoftwareBitmap) { var result = await ocrEngine.RecognizeAsync(bitmap); if (result?.Text != null) { var matchingResults = this.matchExpression.Matches(result.Text); var matched = matchingResults?.Count > 0; if (matched) { // We take the first one, we don't do multiple (yet). ocrDeviceResult.MatchedText = matchingResults[0].Value; ocrDeviceResult.ResultType = OcrMatchResult.Succeeded; ocrDeviceResult.BestOcrSoftwareBitmap?.Dispose(); ocrDeviceResult.BestOcrSoftwareBitmap = null; } else if (result.Text.Length > ocrDeviceResult.BestOcrTextLengthFound) { ocrDeviceResult.BestOcrTextLengthFound = result.Text.Length; ocrDeviceResult.BestOcrSoftwareBitmap?.Dispose(); ocrDeviceResult.BestOcrSoftwareBitmap = SoftwareBitmap.Copy(bitmap); ocrDeviceResult.ResultType = OcrMatchResult.TimedOutCloudCallAvailable; } } } } } }
/// <summary> /// We scan frames from the device, running OCR and trying to find text that matches the pattern /// passed until the point that timeout expires. /// We also try and store the 'best' frame of text that we have seen in case we /// need to later try to submit to the cloud. /// </summary> /// <param name="searchPattern"></param> /// What to look for. /// <param name="timeout"></param> /// How long to spend on it. /// <returns></returns> public async Task <DeviceOcrResult> MatchOnDeviceAsync(TimeSpan timeout) { var deviceOcrResult = new DeviceOcrResult() { ResultType = OcrMatchResult.TimeOutNoCloudCallAvailable }; using (var mediaCapture = new MediaCapture()) { await mediaCapture.InitializeAsync( new MediaCaptureInitializationSettings() { StreamingCaptureMode = StreamingCaptureMode.Video, MemoryPreference = MediaCaptureMemoryPreference.Cpu, SourceGroup = this.mediaFrameSourceFinder.FrameSourceGroup } ); var frameSource = mediaCapture.FrameSources.Single( fs => fs.Value.Info.Id == this.mediaFrameSourceFinder.FrameSourceInfo.Id); // BGRA8 here is intended to line up with what I think the OCR engine supports. using (var reader = await mediaCapture.CreateFrameReaderAsync(frameSource.Value, MediaEncodingSubtypes.Bgra8)) { TaskCompletionSource <bool> completedTask = new TaskCompletionSource <bool>(); var timeoutTask = Task.Delay(timeout); var ocrEngine = OcrEngine.TryCreateFromUserProfileLanguages(); reader.AcquisitionMode = MediaFrameReaderAcquisitionMode.Realtime; int occupiedFlag = 0; TypedEventHandler <MediaFrameReader, MediaFrameArrivedEventArgs> handler = async(s, e) => { if (Interlocked.CompareExchange(ref occupiedFlag, 1, 0) == 0) { await OcrProcessFrameAsync( reader, ocrEngine, deviceOcrResult); if (deviceOcrResult.ResultType == OcrMatchResult.Succeeded) { completedTask.SetResult(true); } Interlocked.Exchange(ref occupiedFlag, 0); } }; reader.FrameArrived += handler; await reader.StartAsync(); var timedOut = (await Task.WhenAny(completedTask.Task, timeoutTask)) == timeoutTask; reader.FrameArrived -= handler; await reader.StopAsync(); } } return(deviceOcrResult); }