/// <summary> /// Attempts to determine the <see cref="BitmapRotation"/> needed to fix the orientation of the given /// <paramref name="imageFile"/>. /// </summary> public async Task <BitmapRotation> TryGetRecommendedRotationAsync(StorageFile imageFile, ImageScannerFormat format) { try { if (OcrEngine != null) { // get separate stream using (IRandomAccessStream sourceStream = await imageFile.OpenAsync(FileAccessMode.Read)) { BitmapDecoder decoder = await BitmapDecoder.CreateAsync(sourceStream); Tuple <BitmapRotation, int> bestRotation; // create rotated 0° SoftwareBitmap bitmap = await decoder.GetSoftwareBitmapAsync(); OcrResult ocrResult = await OcrEngine.RecognizeAsync(bitmap); bestRotation = new Tuple <BitmapRotation, int>(BitmapRotation.None, ocrResult.Text.Length); using (InMemoryRandomAccessStream targetStream = new InMemoryRandomAccessStream()) { // create rotated 90° BitmapEncoder encoder = await HelperService.CreateOptimizedBitmapEncoderAsync(format, targetStream); encoder.SetSoftwareBitmap(bitmap); encoder.BitmapTransform.Rotation = BitmapRotation.Clockwise90Degrees; await encoder.FlushAsync(); decoder = await BitmapDecoder.CreateAsync(targetStream); bitmap = await decoder.GetSoftwareBitmapAsync(); ocrResult = await OcrEngine.RecognizeAsync(bitmap); if (ocrResult.Text.Length > bestRotation.Item2) { bestRotation = new Tuple <BitmapRotation, int>(BitmapRotation.Clockwise90Degrees, ocrResult.Text.Length); } } using (InMemoryRandomAccessStream targetStream = new InMemoryRandomAccessStream()) { // create rotated 180° BitmapEncoder encoder = await HelperService.CreateOptimizedBitmapEncoderAsync(format, targetStream); encoder.SetSoftwareBitmap(bitmap); encoder.BitmapTransform.Rotation = BitmapRotation.Clockwise90Degrees; await encoder.FlushAsync(); decoder = await BitmapDecoder.CreateAsync(targetStream); bitmap = await decoder.GetSoftwareBitmapAsync(); ocrResult = await OcrEngine.RecognizeAsync(bitmap); if (ocrResult.Text.Length > bestRotation.Item2) { bestRotation = new Tuple <BitmapRotation, int>(BitmapRotation.Clockwise180Degrees, ocrResult.Text.Length); } } using (InMemoryRandomAccessStream targetStream = new InMemoryRandomAccessStream()) { // create rotated 270° BitmapEncoder encoder = await HelperService.CreateOptimizedBitmapEncoderAsync(format, targetStream); encoder.SetSoftwareBitmap(bitmap); encoder.BitmapTransform.Rotation = BitmapRotation.Clockwise90Degrees; await encoder.FlushAsync(); decoder = await BitmapDecoder.CreateAsync(targetStream); bitmap = await decoder.GetSoftwareBitmapAsync(); ocrResult = await OcrEngine.RecognizeAsync(bitmap); if (ocrResult.Text.Length > bestRotation.Item2) { bestRotation = new Tuple <BitmapRotation, int>(BitmapRotation.Clockwise270Degrees, ocrResult.Text.Length); } } bitmap.Dispose(); if (bestRotation.Item2 < MinimumNumberOfWords) { // very low confidence, could just be random patterns return(BitmapRotation.None); } else { return(bestRotation.Item1); } } } else { return(BitmapRotation.None); } } catch (Exception exc) { LogService?.Log.Error(exc, "Determining the recommended rotation failed."); AppCenterService?.TrackError(exc); return(BitmapRotation.None); } }