### OcrOptions Builder Usage Example Source: https://github.com/kfrancis/ocr/blob/main/README.md Demonstrates how to create an OcrOptions instance using the Builder pattern, setting language, tryHard, and custom callback. ```csharp var options = new OcrOptions.Builder() .SetLanguage("en-US") .SetTryHard(true) .AddPatternConfig(new OcrPatternConfig(@"\d{10}")) .SetCustomCallback(myCustomCallback) .Build(); ``` -------------------------------- ### OcrViewModel with Straight OcrPlugin Usage Source: https://github.com/kfrancis/ocr/blob/main/README.md Example of an OcrViewModel demonstrating direct usage of OcrPlugin.Default to recognize text without dependency injection. ```csharp public class OcrViewModel { public void DoSomeOcr() { byte[] imageData = GetImageData(); var result = await OcrPlugin.Default.RecognizeTextAsync(imageData); } } ``` -------------------------------- ### Initialize OcrPlugin on App Start Source: https://github.com/kfrancis/ocr/blob/main/tutorial/06_ocrplugin_.md Initialize the OCR service when your application starts to ensure it's ready for use. This is typically done in your App.xaml.cs or equivalent startup file. ```csharp // In your App.xaml.cs or similar startup code protected override async void OnStart() { base.OnStart(); // Initialize the OCR service await OcrPlugin.Default.InitAsync(); // Now the OCR service is ready to use throughout your app } ``` -------------------------------- ### Install MAUI OCR Plugin via .NET CLI Source: https://github.com/kfrancis/ocr/blob/main/README.md Use this command to add the MAUI OCR plugin to your project using the .NET CLI. ```bash dotnet add package Plugin.Maui.OCR ``` -------------------------------- ### Create OcrOptions with Language and Accuracy (Constructor) Source: https://github.com/kfrancis/ocr/blob/main/tutorial/03_ocroptions_.md Use this constructor for basic OcrOptions setup, specifying language and accuracy preference. Suitable for the Xamarin version of the library. ```csharp // Simple options with just language and accuracy setting var options = new OcrOptions( language: "en", // English language tryHard: true // Prioritize accuracy over speed ); ``` -------------------------------- ### Install Xamarin OCR Plugin via .NET CLI Source: https://github.com/kfrancis/ocr/blob/main/README.md Use this command to add the Xamarin OCR plugin to your project using the .NET CLI. ```bash dotnet add package Plugin.Xamarin.OCR ``` -------------------------------- ### Load Raw Asset at Runtime Source: https://github.com/kfrancis/ocr/blob/main/samples/Plugin.Maui.Feature.Sample/Resources/Raw/AboutAssets.txt This C# code demonstrates how to load a raw asset file that was included using the MauiAsset build action. It uses FileSystem.OpenAppPackageFileAsync to get a stream to the asset and then reads its contents. ```csharp async Task LoadMauiAsset() { using var stream = await FileSystem.OpenAppPackageFileAsync("AboutAssets.txt"); using var reader = new StreamReader(stream); var contents = reader.ReadToEnd(); } ``` -------------------------------- ### OcrViewModel with IOcrService Dependency Source: https://github.com/kfrancis/ocr/blob/main/README.md Example of an OcrViewModel that depends on IOcrService via constructor injection. It demonstrates calling RecognizeTextAsync. ```csharp public class OcrViewModel { readonly IOcrService _ocr; public OcrViewModel(IOcrService? ocr) { _ocr = ocr ?? OcrPlugin.Default; } public void DoSomeOcr() { byte[] imageData = GetImageData(); var result = await _ocr.RecognizeTextAsync(imageData); } } ``` -------------------------------- ### Receipt Scanner Example with OCR Pattern Matching Source: https://github.com/kfrancis/ocr/blob/main/tutorial/04_ocrpatternmatcher_.md This C# snippet shows how to initialize an OCR service, define pattern configurations for extracting specific data (like total amount and date) using regex and validation functions, and then perform OCR on a receipt image to extract this information. It's useful for automating data extraction from structured documents. ```csharp IOcrService ocrService = /* get the service */; await ocrService.InitAsync(); var totalConfig = new OcrPatternConfig( regexPattern: @"Total:?\s*\$\d+\.\d{{2}}", validationFunction: text => text.Contains("$") ); var dateConfig = new OcrPatternConfig( regexPattern: @"\d{{1,2}}/\d{{1,2}}/\d{{4}}", validationFunction: text => DateTime.TryParse(text, out _) ); var options = new OcrOptions( language: "en", tryHard: true, patternConfigs: new List { totalConfig, dateConfig } ); byte[] imageBytes = File.ReadAllBytes("receipt.jpg"); OcrResult result = await ocrService.RecognizeTextAsync(imageBytes, options); if (result.Success) { Console.WriteLine("Receipt text: " + result.AllText); if (result.MatchedValues.Count > 0) { Console.WriteLine("\nExtracted information:"); foreach (string value in result.MatchedValues) { Console.WriteLine($" {value}"); } } } ``` -------------------------------- ### Android OCR Implementation Example Source: https://github.com/kfrancis/ocr/blob/main/tutorial/05_ocrimplementation_.md A simplified look at the Android implementation of IOcrService. It demonstrates converting image bytes to a bitmap, creating an ML Kit input image, selecting a text recognizer based on options, processing the image, and converting the ML Kit result to OcrResult. ```csharp // From OcrImplementation.android.cs internal class OcrImplementation : IOcrService { // Platform-specific OCR engine private static ITextRecognizer? s_textRecognizer; public async Task RecognizeTextAsync(byte[] imageData, OcrOptions options, CancellationToken ct = default) { // Convert byte array to Android bitmap using var srcBitmap = await BitmapFactory.DecodeByteArrayAsync(imageData, 0, imageData.Length); // Create ML Kit input image using var srcImage = InputImage.FromBitmap(srcBitmap, 0); // Get or create text recognizer based on options ITextRecognizer textScanner; if (options.TryHard) { // Use more accurate but slower recognizer textScanner = TextRecognition.GetClient(new TextRecognizerOptions.Builder() .SetExecutor(/* executor */) .Build()); } else { // Use faster on-device recognizer textScanner = TextRecognition.GetClient(TextRecognizerOptions.DefaultOptions); } // Process the image var result = await textScanner.Process(srcImage).AsAsync(); // Convert ML Kit result to OcrResult return ProcessOcrResult(result, options); } // Other methods... } ``` -------------------------------- ### Start Recognizing Text Asynchronously Source: https://github.com/kfrancis/ocr/blob/main/README.md Initiates an asynchronous OCR recognition task using StartRecognizeTextAsync, which fires a RecognitionCompleted event upon completion. ```csharp var result = await OcrPlugin.Default.StartRecognizeTextAsync(imageData, options); ``` -------------------------------- ### IOcrService.StartRecognizeTextAsync Source: https://github.com/kfrancis/ocr/blob/main/README.md Starts an asynchronous operation to recognize text from image data using specified OCR options. This method is non-blocking. ```APIDOC ## StartRecognizeTextAsync ### Description Starts an asynchronous operation to recognize text from image data using specified OCR options. This method is non-blocking. ### Method Task ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body - **imageData** (byte[]) - Required - The image data to recognize text from. - **options** (OcrOptions) - Required - The OCR options to configure the recognition process. - **ct** (CancellationToken) - Optional - A token to observe for cancellation requests. ### Request Example None ### Response #### Success Response None #### Response Example None ``` -------------------------------- ### Start Asynchronous Text Recognition Source: https://github.com/kfrancis/ocr/blob/main/tutorial/01_iocrservice_interface_.md Initiates an asynchronous text recognition process for an image byte array with specified OcrOptions. The result will be delivered via the RecognitionCompleted event. ```csharp Task StartRecognizeTextAsync(byte[] imageData, OcrOptions options, CancellationToken ct = default); ``` -------------------------------- ### Combining Multiple OCR Patterns Source: https://github.com/kfrancis/ocr/blob/main/tutorial/04_ocrpatternmatcher_.md Combine various OcrPatternConfig objects into a list to extract different types of information from OCR text. This example includes patterns for emails, phone numbers, and websites. ```csharp // Create a list of pattern configs var patternConfigs = new List { // Email pattern new OcrPatternConfig(@"[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}"), // Phone pattern new OcrPatternConfig(@"\(?\d{3}\)?[-.\s]?\d{3}[-.\s]?\d{4}"), // Website pattern new OcrPatternConfig(@"https?://[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}") }; // Create OCR options with these patterns var options = new OcrOptions( language: "en", patternConfigs: patternConfigs ); ``` -------------------------------- ### Implementing Custom Validation Logic Source: https://github.com/kfrancis/ocr/blob/main/tutorial/04_ocrpatternmatcher_.md Implement complex validation logic within the validation function of an OcrPatternConfig. This example demonstrates basic validation for credit card numbers, including length checks. ```csharp // Pattern config for credit card numbers with validation var creditCardConfig = new OcrPatternConfig( regexPattern: @"\d{4}[-\s]?\d{4}[-\s]?\d{4}[-\s]?\d{4}", validationFunction: text => { // Remove spaces and dashes string digits = text.Replace(" ", "").Replace("-", ""); // Check if it's a valid length if (digits.Length != 16) return false; // Implement Luhn algorithm for credit card validation // (simplified for this example) return true; } ); ``` -------------------------------- ### Specify OCR Language Source: https://github.com/kfrancis/ocr/blob/main/tutorial/03_ocroptions_.md Set the expected language for OCR using BCP-47 codes. Example: 'en' for English. ```csharp public string? Language { get; } ``` -------------------------------- ### Create OcrOptions with Builder Pattern (MAUI) Source: https://github.com/kfrancis/ocr/blob/main/tutorial/03_ocroptions_.md Utilize the builder pattern for a fluent and readable OcrOptions configuration, including language, accuracy, and custom pattern matching. This approach is for the MAUI version. ```csharp // Create options using the builder pattern var options = new OcrOptions.Builder() .SetLanguage("en") .SetTryHard(true) .AddPatternConfig(new OcrPatternConfig( regexPattern: @"\d{3}-\d{2}-\d{4}", validationFunction: text => text.Length == 11 )) .Build(); ``` -------------------------------- ### Configure OcrOptions for Receipt Scanning in C# Source: https://github.com/kfrancis/ocr/blob/main/tutorial/03_ocroptions_.md This snippet demonstrates how to create OcrOptions for receipt scanning, specifying the language, enabling TryHard for better accuracy, and configuring patterns to extract total amounts and dates with validation. ```csharp var options = new OcrOptions( language: "en", tryHard: true, patternConfigs: new List { // Total amount pattern (e.g., $123.45) new OcrPatternConfig( @"\$\d+\.\d{2}", amount => decimal.TryParse(amount.TrimStart('$'), out _) ), // Date pattern (e.g., 01/02/2023) new OcrPatternConfig( @"\d{1,2}/\d{1,2}/\d{4}", date => DateTime.TryParse(date, out _) ) } ); // Recognize text in the receipt image OcrResult result = await ocrService.RecognizeTextAsync(receiptImageBytes, options); // Extract information from the result if (result.Success) { Console.WriteLine("Receipt text: " + result.AllText); if (result.MatchedValues.Count > 0) { Console.WriteLine("Found important information:"); foreach (string value in result.MatchedValues) { Console.WriteLine($" {value}"); } } } ``` -------------------------------- ### C# Receipt Scanner with OCR Options Source: https://github.com/kfrancis/ocr/blob/main/tutorial/05_ocrimplementation_.md This C# snippet demonstrates how to initialize an OCR service, configure it with a specific pattern for prices, and recognize text from a receipt image. It highlights cross-platform compatibility. ```csharp // Get the OCR service (we'll learn how in the next chapter) IOcrService ocrService = /* get the service */; // Initialize the service await ocrService.InitAsync(); // Create options for receipt scanning var options = new OcrOptions( language: "en", tryHard: true, patternConfig: new OcrPatternConfig( regexPattern: @"\$\d+\.\d{{2}}", // Pattern for prices validationFunction: text => decimal.TryParse(text.TrimStart('$'), out _) ) ); // Load a receipt image (e.g., from camera or file) byte[] imageBytes = /* get image bytes */; // Recognize text in the receipt OcrResult result = await ocrService.RecognizeTextAsync(imageBytes, options); // Check if OCR was successful if (result.Success) { Console.WriteLine("Receipt text: " + result.AllText); // Display matched prices if (result.MatchedValues.Count > 0) { Console.WriteLine("Found prices:"); foreach (string price in result.MatchedValues) { Console.WriteLine($" {price}"); } } } ``` -------------------------------- ### Basic OcrPlugin Usage for Text Recognition Source: https://github.com/kfrancis/ocr/blob/main/tutorial/06_ocrplugin_.md Demonstrates how to access the OCR service via OcrPlugin.Default, initialize it, load an image, and recognize text. Ensure the image file exists at the specified path. ```csharp // Access the OCR service through OcrPlugin IOcrService ocrService = OcrPlugin.Default; // Initialize the service (only needed once) await ocrService.InitAsync(); // Load an image byte[] imageBytes = File.ReadAllBytes("document.jpg"); // Recognize text in the image OcrResult result = await ocrService.RecognizeTextAsync(imageBytes); // Check if OCR was successful if (result.Success) { Console.WriteLine("Recognized text: " + result.AllText); } ``` -------------------------------- ### Get Supported OCR Languages Source: https://github.com/kfrancis/ocr/blob/main/tutorial/01_iocrservice_interface_.md This property returns a read-only collection of strings, indicating all the languages that the current OCR service implementation supports for text recognition. ```csharp IReadOnlyCollection SupportedLanguages { get; } ``` -------------------------------- ### Include Raw Assets in .csproj Source: https://github.com/kfrancis/ocr/blob/main/samples/Plugin.Maui.Feature.Sample/Resources/Raw/AboutAssets.txt This snippet shows how to configure your .csproj file to include all files in the Resources\Raw directory and its subdirectories as MauiAssets. The LogicalName ensures the file is deployed with the correct relative path. ```xml ``` -------------------------------- ### Android Manifest Configuration for OCR Source: https://github.com/kfrancis/ocr/blob/main/README.md Configures the Android application to automatically download the necessary OCR model upon installation. This metadata should be placed within the application tag in AndroidManifest.xml. ```xml ``` -------------------------------- ### OcrOptions Builder Pattern Implementation Source: https://github.com/kfrancis/ocr/blob/main/tutorial/03_ocroptions_.md Demonstrates the nested Builder class for creating OcrOptions objects. Setter methods allow for chaining, and the Build() method constructs the final object. ```csharp public class Builder { private string? _language; private bool _tryHard; private List _patternConfigs = new(); private CustomOcrValidationCallback? _customCallback; public Builder SetLanguage(string language) { _language = language; return this; } public Builder SetTryHard(bool tryHard) { _tryHard = tryHard; return this; } // Other setter methods... public OcrOptions Build() { return new OcrOptions(_language, _tryHard, _patternConfigs, _customCallback); } } ``` -------------------------------- ### Extracting Specific Data with Capture Groups Source: https://github.com/kfrancis/ocr/blob/main/tutorial/04_ocrpatternmatcher_.md Use capture groups in regex patterns to extract specific parts of a matched string. This example extracts the monetary amount from a 'Total' string. ```csharp // Pattern config for extracting just the amount from "Total: $42.99" var totalConfig = new OcrPatternConfig( regexPattern: @"Total:?\s*\$(\d+\.\d{2})", validationFunction: text => { // Extract just the amount using a regex var match = Regex.Match(text, @"Total:?\s*\$(\d+\.\d{2})"); if (match.Success && match.Groups.Count > 1) { // Return just the amount part return match.Groups[1].Value; } return text; } ); ``` -------------------------------- ### Enabling OCR in MAUI App Startup Source: https://github.com/kfrancis/ocr/blob/main/tutorial/07_useocr_extension_method_.md This C# code demonstrates how to integrate the UseOcr extension method into your MAUI application's startup process in MauiProgram.cs to enable OCR functionality. ```csharp // In your MauiProgram.cs public static MauiApp CreateMauiApp() { var builder = MauiApp.CreateBuilder(); builder .UseMauiApp() .ConfigureFonts(fonts => { fonts.AddFont("OpenSans-Regular.ttf", "OpenSansRegular"); fonts.AddFont("OpenSans-Semibold.ttf", "OpenSansSemibold"); }) .UseOcr(); // Add this line to enable OCR return builder.Build(); } ``` -------------------------------- ### Create OcrOptions with Pattern Matching (Constructor) Source: https://github.com/kfrancis/ocr/blob/main/tutorial/03_ocroptions_.md Configure OcrOptions with advanced pattern matching for specific text formats, alongside language and accuracy settings. This is for the Xamarin version. ```csharp // More complex options with pattern matching var options = new OcrOptions( language: "en", tryHard: true, patternConfig: new OcrPatternConfig( regexPattern: @"\d{3}-\d{2}-\d{4}", // Pattern for SSN validationFunction: text => text.Length == 11 ) ); ``` -------------------------------- ### Register Custom OCR Service in MAUI Source: https://github.com/kfrancis/ocr/blob/main/tutorial/06_ocrplugin_.md Demonstrates how to register a custom IOcrService implementation using dependency injection in a MAUI application's MauiProgram.cs file. This allows for custom OCR logic or testing. ```csharp public static MauiApp CreateMauiApp() { var builder = MauiApp.CreateBuilder(); // Register your custom OCR service builder.Services.AddSingleton(); // Add the OCR plugin builder.UseOcr(); return builder.Build(); } ``` -------------------------------- ### Accessing OcrResult Elements with Position Source: https://github.com/kfrancis/ocr/blob/main/tutorial/02_ocrresult_.md Iterate through the 'Elements' property of an OcrResult to get detailed information about each recognized word, including its text, coordinates, dimensions, and confidence score. The confidence is formatted as a percentage. ```csharp Console.WriteLine("\nWords:"); foreach (var element in result.Elements) { Console.WriteLine($" Text: {element.Text}"); Console.WriteLine($" Position: ({element.X}, {element.Y})"); Console.WriteLine($" Size: {element.Width}x{element.Height}"); Console.WriteLine($" Confidence: {element.Confidence:P}"); Console.WriteLine(); } ``` -------------------------------- ### Initialize OCR Service Source: https://github.com/kfrancis/ocr/blob/main/tutorial/01_iocrservice_interface_.md This asynchronous method is responsible for initializing the OCR service on the specific platform. It requires a CancellationToken to manage the initialization process. ```csharp Task InitAsync(CancellationToken ct = default); ``` -------------------------------- ### Scan Receipt and Extract Total with IOcrService Source: https://github.com/kfrancis/ocr/blob/main/tutorial/07_useocr_extension_method_.md Implement a ViewModel to utilize the injected IOcrService for scanning receipt images. This snippet demonstrates configuring OCR options for pattern matching and extracting specific data like prices. ```csharp // In ScanViewModel.cs public class ScanViewModel { private readonly IOcrService _ocrService; public ScanViewModel(IOcrService ocrService) { _ocrService = ocrService; } public async Task ScanReceiptAsync(byte[] imageBytes) { // Create options for receipt scanning var options = new OcrOptions( language: "en", patternConfig: new OcrPatternConfig( @"\$\d+\.\d{{2}}" // Pattern for prices ) ); // Recognize text in the receipt var result = await _ocrService.RecognizeTextAsync(imageBytes, options); // Return the total amount if found if (result.MatchedValues.Count > 0) { return $"Total: {result.MatchedValues[0]}"; } return "No total found"; } } ``` -------------------------------- ### IOcrService Interface Methods Source: https://github.com/kfrancis/ocr/blob/main/tutorial/05_ocrimplementation_.md These are the common methods provided by all OcrImplementation classes, defined in the IOcrService interface. They allow for initialization and text recognition from image data across different platforms. ```csharp // Initialize the OCR service Task InitAsync(CancellationToken ct = default); // Recognize text in an image Task RecognizeTextAsync(byte[] imageData, bool tryHard = false, CancellationToken ct = default); Task RecognizeTextAsync(byte[] imageData, OcrOptions options, CancellationToken ct = default); // Start asynchronous recognition Task StartRecognizeTextAsync(byte[] imageData, OcrOptions options, CancellationToken ct = default); ``` -------------------------------- ### Custom OCR with OcrOptions Source: https://github.com/kfrancis/ocr/blob/main/tutorial/06_ocrplugin_.md Demonstrates how to use OcrPlugin with OcrOptions to specify language, enable 'tryHard' mode, and define custom regex patterns with validation functions for text recognition. This is useful for targeted extraction of specific data formats like SSNs. ```csharp IOcrService ocrService = OcrPlugin.Default; await ocrService.InitAsync(); var options = new OcrOptions( language: "en", tryHard: true, patternConfig: new OcrPatternConfig( regexPattern: @"\d{3}-\d{2}-\d{4}", // Pattern for SSN validationFunction: text => text.Length == 11 ) ); byte[] imageBytes = File.ReadAllBytes("document.jpg"); OcrResult result = await ocrService.RecognizeTextAsync(imageBytes, options); if (result.MatchedValues.Count > 0) { Console.WriteLine($"Found SSN: {result.MatchedValues[0]}"); } ``` -------------------------------- ### Recognize Text with Options Source: https://github.com/kfrancis/ocr/blob/main/README.md Demonstrates calling RecognizeTextAsync with specific OcrOptions, allowing for custom language and settings. ```csharp var result = await OcrPlugin.Default.RecognizeTextAsync(imageData, options); ``` -------------------------------- ### Register OcrPlugin with Dependency Injection Source: https://github.com/kfrancis/ocr/blob/main/README.md Shows how to register the OcrPlugin as a singleton service for dependency injection in a .NET MAUI application. ```csharp builder.Services.AddSingleton(OcrPlugin.Default); ``` -------------------------------- ### Registering IOcrService with MauiAppBuilder Source: https://github.com/kfrancis/ocr/blob/main/tutorial/07_useocr_extension_method_.md This C# code snippet shows how to implement the UseOcr extension method for MauiAppBuilder. It registers the OcrImplementation as a singleton for the IOcrService within the DI container, enabling method chaining. ```csharp namespace Plugin.Maui.OCR; public static class OcrServiceExtensions { public static MauiAppBuilder UseOcr(this MauiAppBuilder builder) { // Register the IOcrService implementation with the DI container. // This ensures that whenever IOcrService is injected, the specific // platform implementation is provided. builder.Services.AddSingleton(); return builder; } } ``` -------------------------------- ### Select Photo from File Source: https://github.com/kfrancis/ocr/blob/main/tutorial/08_mainpage__sample_app__.md Initiates the device's file picker to allow the user to select a photo. Handles the result by processing the photo and displaying recognized text. ```csharp private async void OpenFromFileBtn_Clicked(object sender, EventArgs e) { var photo = await MediaPicker.Default.PickPhotoAsync(); if (photo != null) { var result = await ProcessPhoto(photo); ResultLbl.Text = result.AllText; NoImagePlaceholder.IsVisible = false; } } ``` -------------------------------- ### OcrOptions Class Structure Source: https://github.com/kfrancis/ocr/blob/main/tutorial/03_ocroptions_.md Shows the private constructor and public properties of the OcrOptions class. This class uses the builder pattern for instantiation. ```csharp public sealed class OcrOptions { private OcrOptions(string? language, bool tryHard, List patternConfigs, CustomOcrValidationCallback? customCallback) { Language = language; TryHard = tryHard; PatternConfigs = patternConfigs; CustomCallback = customCallback; } public CustomOcrValidationCallback? CustomCallback { get; } public string? Language { get; } public List PatternConfigs { get; } public bool TryHard { get; } // Builder class implementation... } ``` -------------------------------- ### Basic IOcrService Text Recognition Source: https://github.com/kfrancis/ocr/blob/main/tutorial/01_iocrservice_interface_.md Use this snippet to perform basic text recognition from an image. Ensure the IOcrService is initialized and an image is loaded. ```csharp // 1. Get access to the OCR service IOcrService ocrService = /* we'll learn how to get this in later chapters */; // 2. Initialize the service await ocrService.InitAsync(); // 3. Load an image (for example, from a file) byte[] imageBytes = File.ReadAllBytes("receipt.jpg"); // 4. Recognize text in the image OcrResult result = await ocrService.RecognizeTextAsync(imageBytes); // 5. Use the recognized text if (result.Success) { Console.WriteLine("Recognized text: " + result.AllText); // Print each line separately foreach (string line in result.Lines) { Console.WriteLine($"Line: {line}"); } } ``` -------------------------------- ### Windows OCR Service Implementation Source: https://github.com/kfrancis/ocr/blob/main/tutorial/05_ocrimplementation_.md This C# code demonstrates how to implement the IOcrService interface for Windows. It handles image conversion, OCR engine initialization, and result processing using the Windows OCR API. ```csharp // From OcrImplementation.windows.cs class OcrImplementation : IOcrService { public async Task RecognizeTextAsync(byte[] imageData, OcrOptions options, CancellationToken ct = default) { // Create OCR engine var ocrEngine = OcrEngine.TryCreateFromUserProfileLanguages(); // Convert byte array to stream using var stream = new InMemoryRandomAccessStream(); await stream.WriteAsync(imageData.AsBuffer()); stream.Seek(0); // Decode image var decoder = await BitmapDecoder.CreateAsync(stream); var softwareBitmap = await decoder.GetSoftwareBitmapAsync(); // Process the image var ocrResult = await ocrEngine.RecognizeAsync(softwareBitmap); // Convert Windows OCR result to OcrResult return ProcessOcrResult(ocrResult, options); } // Other methods... } ``` -------------------------------- ### MainPage Class Structure Source: https://github.com/kfrancis/ocr/blob/main/tutorial/08_mainpage__sample_app__.md Defines the basic structure of the MainPage, including dependency injection for the IOcrService and initialization logic. ```csharp public partial class MainPage { private readonly IOcrService _ocr; private byte[] _originalImageData; private byte[] _preprocessedImageData; public MainPage(IOcrService feature) { InitializeComponent(); _ocr = feature; } protected override async void OnAppearing() { base.OnAppearing(); await _ocr.InitAsync(); } // Other methods... } ``` -------------------------------- ### OcrOptions Class Definition Source: https://github.com/kfrancis/ocr/blob/main/README.md Defines the OcrOptions class with properties for language, tryHard, pattern configurations, and custom callbacks. Includes a private constructor and a nested Builder class. ```csharp public class OcrOptions { public string? Language { get; } public bool TryHard { get; } public List PatternConfigs { get; } public CustomOcrValidationCallback? CustomCallback { get; } private OcrOptions(string? language, bool tryHard, List patternConfigs, CustomOcrValidationCallback? customCallback) { Language = language; TryHard = tryHard; PatternConfigs = patternConfigs; CustomCallback = customCallback; } public class Builder { private string? _language; private bool _tryHard; private List _patternConfigs = new List(); private CustomOcrValidationCallback? _customCallback; public Builder SetLanguage(string language) { _language = language; return this; } public Builder SetTryHard(bool tryHard) { _tryHard = tryHard; return this; } public Builder AddPatternConfig(OcrPatternConfig patternConfig) { _patternConfigs.Add(patternConfig); return this; } public Builder SetPatternConfigs(List patternConfigs) { _patternConfigs = patternConfigs ?? new List(); return this; } public Builder SetCustomCallback(CustomOcrValidationCallback customCallback) { _customCallback = customCallback; return this; } public OcrOptions Build() { return new OcrOptions(_language, _tryHard, _patternConfigs, _customCallback); } } } ``` -------------------------------- ### Handle Camera Photo Capture and Event Subscription Source: https://github.com/kfrancis/ocr/blob/main/tutorial/08_mainpage__sample_app__.md This C# code captures a photo using the device camera and subscribes to the `RecognitionCompleted` event for asynchronous OCR processing. Ensure the `MediaPicker.Default.IsCaptureSupported` check is performed before attempting to capture. ```csharp private async void OpenFromCameraUseEventBtn_Clicked(object sender, EventArgs e) { if (MediaPicker.Default.IsCaptureSupported) { var photo = await MediaPicker.Default.CapturePhotoAsync(); if (photo == null) { return; } _ocr.RecognitionCompleted += OnRecognitionCompleted; await StartProcessingPhoto(photo); } else { await DisplayAlert("Sorry", "Image capture is not supported on this device.", "OK"); } } ``` -------------------------------- ### Register OCR Service in MauiProgram.cs Source: https://github.com/kfrancis/ocr/blob/main/tutorial/07_useocr_extension_method_.md Register the OCR service using the UseOcr extension method during application startup. This makes the OCR service available for dependency injection throughout the application. ```csharp // In MauiProgram.cs public static MauiApp CreateMauiApp() { var builder = MauiApp.CreateBuilder(); builder .UseMauiApp() .UseOcr(); // Register OCR service // Register pages and view models builder.Services.AddTransient(); builder.Services.AddTransient(); return builder.Build(); } ``` -------------------------------- ### Accessing Raw Assets in Xamarin.Android Source: https://github.com/kfrancis/ocr/blob/main/samples/Plugin.Xamarin.OCR.Sample/Plugin.Xamarin.OCR.Sample.Android/Assets/AboutAssets.txt Demonstrates how to open and read a raw asset file using the AssetManager in a Xamarin.Android Activity. Ensure the file has a Build Action of 'AndroidAsset'. ```C# public class ReadAsset : Activity { protected override void OnCreate (Bundle bundle) { base.OnCreate (bundle); InputStream input = Assets.Open ("my_asset.txt"); } } ``` -------------------------------- ### Recognize Text with Basic OcrOptions Source: https://github.com/kfrancis/ocr/blob/main/tutorial/03_ocroptions_.md Use OcrOptions to specify language and accuracy settings for text recognition. Load an image and process it with the IOcrService. ```csharp IOcrService ocrService = /* get the service */; await ocrService.InitAsync(); var options = new OcrOptions( language: "en", tryHard: true ); byte[] imageBytes = File.ReadAllBytes("receipt.jpg"); OcrResult result = await ocrService.RecognizeTextAsync(imageBytes, options); if (result.Success) { Console.WriteLine("Recognized text: " + result.AllText); } ``` -------------------------------- ### Recognize Text with Basic Options Source: https://github.com/kfrancis/ocr/blob/main/tutorial/01_iocrservice_interface_.md Use this method to recognize text from an image byte array with optional 'tryHard' flag for enhanced accuracy. A CancellationToken is used for asynchronous operations. ```csharp Task RecognizeTextAsync(byte[] imageData, bool tryHard = false, CancellationToken ct = default); ``` -------------------------------- ### Configure OcrOptions for Multiple Pattern Matching Source: https://github.com/kfrancis/ocr/blob/main/tutorial/03_ocroptions_.md Use this snippet to create OcrOptions that search for multiple regular expression patterns simultaneously. Specify patterns within the patternConfigs list. ```csharp // Create options with multiple pattern matching var options = new OcrOptions( language: "en", patternConfigs: new List { // Email pattern new OcrPatternConfig( @"[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}" ), // Phone pattern new OcrPatternConfig( @"\(?\d{3}\)?[-.\s]?\d{3}[-.\s]?\d{4}" ) } ); ``` -------------------------------- ### OCR Service Usage (App Code) Source: https://github.com/kfrancis/ocr/blob/main/tutorial/05_ocrimplementation_.md This snippet shows how an application typically uses the IOcrService interface to recognize text from image bytes. The actual platform-specific implementation is called behind the scenes. ```csharp IOcrService ocrService = /* get the service */; OcrResult result = await ocrService.RecognizeTextAsync(imageBytes); ``` -------------------------------- ### Configuring OcrOptions with Multiple Patterns Source: https://github.com/kfrancis/ocr/blob/main/tutorial/04_ocrpatternmatcher_.md Integrate OcrPatternMatcher by defining multiple OcrPatternConfig objects within OcrOptions to extract various data types like amounts and dates from OCR results. ```csharp // Create OCR options with pattern matching for receipts var options = new OcrOptions( language: "en", patternConfigs: new List { // Pattern for total amount (e.g., $42.99) new OcrPatternConfig( regexPattern: @"\\$\d+\\.\\d{{2}}", validationFunction: amount => decimal.TryParse(amount.TrimStart('$'), out _) ), // Pattern for date (e.g., 05/15/2023) new OcrPatternConfig( regexPattern: @"\d{{1,2}}/\d{{1,2}}/\d{{4}}", validationFunction: date => DateTime.TryParse(date, out _) ) } ); // Perform OCR with these options OcrResult result = await ocrService.RecognizeTextAsync(imageBytes, options); // Access the matched values foreach (string match in result.MatchedValues) { Console.WriteLine($"Found: {match}"); } ``` -------------------------------- ### Advanced IOcrService Text Recognition with Options Source: https://github.com/kfrancis/ocr/blob/main/tutorial/01_iocrservice_interface_.md Utilize this snippet for advanced text recognition, allowing customization through OcrOptions. This is useful for specifying languages, improving accuracy, or extracting specific patterns. ```csharp // Create options for OCR var options = new OcrOptions( language: "en", // English language tryHard: true, // More accurate but slower patternConfig: new OcrPatternConfig( regexPattern: @"\d{3}-\d{2}-\d{4}", // Pattern for SSN validationFunction: text => text.Length == 11 ) ); // Recognize text with options OcrResult result = await ocrService.RecognizeTextAsync(imageBytes, options); // Check if any patterns were matched if (result.MatchedValues.Count > 0) { Console.WriteLine($"Found SSN: {result.MatchedValues[0]}"); } ``` -------------------------------- ### Extracting Patterns with OcrResult Source: https://github.com/kfrancis/ocr/blob/main/tutorial/02_ocrresult_.md Use this snippet to configure OCR options with custom regex patterns for email and phone numbers, perform OCR, and then iterate through any matched values found in the result. Ensure the OcrService is initialized and the image data is available. ```csharp var options = new OcrOptions( patternConfigs: new List { new OcrPatternConfig(@"[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}"), // Email new OcrPatternConfig(@"\(?\d{3}\)?[-.\s]?\d{3}[-.\s]?\d{4}") // Phone } ); OcrResult result = await ocrService.RecognizeTextAsync(imageBytes, options); if (result.MatchedValues.Count > 0) { Console.WriteLine("\nFound patterns:"); foreach (string match in result.MatchedValues) { Console.WriteLine($" {match}"); } } ``` -------------------------------- ### Preprocess Image for OCR Source: https://github.com/kfrancis/ocr/blob/main/tutorial/08_mainpage__sample_app__.md Resizes large images and applies contrast, blur, and binary thresholding to prepare them for OCR. Load the image from a byte array and return the preprocessed image as a byte array. ```csharp private static async Task PreprocessImageForOcr(byte[] imageData) { await using var ms = new MemoryStream(imageData); using var image = await Image.LoadAsync(ms); // Resize large images to improve processing speed const int MaxDimension = 1500; if (image.Width > MaxDimension || image.Height > MaxDimension) { var ratio = Math.Min((float)MaxDimension / image.Width, (float)MaxDimension / image.Height); var newWidth = (int)(image.Width * ratio); var newHeight = (int)(image.Height * ratio); image.Mutate(x => x.Resize(newWidth, newHeight)); } // Apply preprocessing steps image.Mutate(x => x .Contrast(1.2f) // Boost contrast .GaussianBlur(1.1f) // Slight blur to reduce noise .BinaryThreshold(0.45f) // Convert to black and white ); // Convert back to byte array using var resultMs = new MemoryStream(); await image.SaveAsPngAsync(resultMs); return resultMs.ToArray(); } ``` -------------------------------- ### Registering IOcrService with UseOcr Source: https://github.com/kfrancis/ocr/blob/main/tutorial/07_useocr_extension_method_.md This C# code defines the UseOcr extension method for MauiAppBuilder. It registers OcrImplementation as the IOcrService with the dependency injection container. ```csharp public static MauiAppBuilder UseOcr(this MauiAppBuilder builder) { // Register the IOcrService implementation with the DI container builder.Services.AddSingleton(); return builder; } ``` -------------------------------- ### IOcrService.InitAsync Source: https://github.com/kfrancis/ocr/blob/main/README.md Initializes the OCR service. This method should be called before any recognition operations. ```APIDOC ## InitAsync ### Description Initializes the OCR service. This method should be called before any recognition operations. ### Method Task ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Request Example None ### Response #### Success Response None #### Response Example None ``` -------------------------------- ### Loading Fonts from Assets in Xamarin.Android Source: https://github.com/kfrancis/ocr/blob/main/samples/Plugin.Xamarin.OCR.Sample/Plugin.Xamarin.OCR.Sample.Android/Assets/AboutAssets.txt Shows how to load a font file directly from the assets directory using Typeface.CreateFromAsset. The font file should be placed in a subdirectory within the Assets folder. ```C# Typeface tf = Typeface.CreateFromAsset (Context.Assets, "fonts/samplefont.ttf"); ``` -------------------------------- ### Registering a Custom OCR Service in MAUI Source: https://github.com/kfrancis/ocr/blob/main/tutorial/07_useocr_extension_method_.md Register your custom IOcrService implementation with the DI container before calling UseOcr. This ensures your custom service takes precedence over the default one. ```csharp public static MauiApp CreateMauiApp() { var builder = MauiApp.CreateBuilder(); builder .UseMauiApp() .ConfigureFonts(fonts => { fonts.AddFont("OpenSans-Regular.ttf", "OpenSansRegular"); fonts.AddFont("OpenSans-Semibold.ttf", "OpenSansSemibold"); }); // Register your custom OCR service builder.Services.AddSingleton(); // Call UseOcr (it won't override your custom registration) builder.UseOcr(); return builder.Build(); } ``` -------------------------------- ### Use OcrPlugin in Gallery Page Source: https://github.com/kfrancis/ocr/blob/main/tutorial/06_ocrplugin_.md Recognize text from an image selected from the gallery. This snippet demonstrates converting a selected image to bytes and then using OcrPlugin for text extraction. ```csharp // In your GalleryPage.xaml.cs private async void ImageSelected(object sender, SelectedItemChangedEventArgs e) { // Get the selected image var image = e.SelectedItem as ImageSource; // Convert image to byte array byte[] imageBytes = ConvertToByteArray(image); // Recognize text using OcrPlugin var result = await OcrPlugin.Default.RecognizeTextAsync(imageBytes); // Display the result ResultLabel.Text = result.AllText; } ``` -------------------------------- ### Use OcrPlugin in Camera Page Source: https://github.com/kfrancis/ocr/blob/main/tutorial/06_ocrplugin_.md Recognize text from an image captured by the camera. This snippet shows how to take a photo, convert it to bytes, and then use OcrPlugin to extract text. ```csharp // In your CameraPage.xaml.cs private async void ScanButton_Clicked(object sender, EventArgs e) { // Take a photo var photo = await TakePhotoAsync(); // Convert photo to byte array byte[] imageBytes = ConvertToByteArray(photo); // Recognize text using OcrPlugin var result = await OcrPlugin.Default.RecognizeTextAsync(imageBytes); // Display the result ResultLabel.Text = result.AllText; } ``` -------------------------------- ### Process Photo with OCR in MAUI Source: https://github.com/kfrancis/ocr/blob/main/README.md Inject IOcrService and use RecognizeTextAsync to process image data from a photo. ```csharp /// /// Takes a photo and processes it using the OCR service. /// /// The photo to process. /// The OCR result. private async Task ProcessPhoto(FileResult photo) { // Open a stream to the photo using var sourceStream = await photo.OpenReadAsync(); // Create a byte array to hold the image data var imageData = new byte[sourceStream.Length]; // Read the stream into the byte array await sourceStream.ReadAsync(imageData); // Process the image data using the OCR service return await _ocr.RecognizeTextAsync(imageData); } ``` -------------------------------- ### Accessing IOcrService via Constructor Injection Source: https://github.com/kfrancis/ocr/blob/main/tutorial/07_useocr_extension_method_.md Inject the IOcrService into your page's constructor to easily access OCR functionality. The DI container automatically provides an instance of the OCR service. ```csharp public class ScanPage : ContentPage { private readonly IOcrService _ocrService; // The IOcrService is automatically injected by the DI container public ScanPage(IOcrService ocrService) { _ocrService = ocrService; InitializeComponent(); } private async void ScanButton_Clicked(object sender, EventArgs e) { // Take a photo var photo = await TakePhotoAsync(); // Convert photo to byte array byte[] imageBytes = ConvertToByteArray(photo); // Recognize text using the injected OCR service var result = await _ocrService.RecognizeTextAsync(imageBytes); // Display the result ResultLabel.Text = result.AllText; } } ``` -------------------------------- ### Capture Image from Camera Source: https://github.com/kfrancis/ocr/blob/main/tutorial/08_mainpage__sample_app__.md Handles capturing a photo using the device's camera, processing it with OCR, and displaying the recognized text. Checks for camera capture support before proceeding. ```csharp private async void OpenFromCameraBtn_Clicked(object sender, EventArgs e) { if (MediaPicker.Default.IsCaptureSupported) { var photo = await MediaPicker.Default.CapturePhotoAsync(); if (photo == null) { return; } var result = await ProcessPhoto(photo); ResultLbl.Text = result.AllText; NoImagePlaceholder.IsVisible = false; } else { await DisplayAlert("Sorry", "Image capture is not supported on this device.", "OK"); } } ``` -------------------------------- ### OcrPlugin Static Class Definition Source: https://github.com/kfrancis/ocr/blob/main/tutorial/06_ocrplugin_.md Defines the static OcrPlugin class which manages the default OCR service implementation. The default service is lazily initialized upon first access. ```csharp public static class OcrPlugin { private static IOcrService? s_defaultImplementation; public static IOcrService Default => s_defaultImplementation ??= new OcrImplementation(); internal static void SetDefault(IOcrService? implementation) => s_defaultImplementation = implementation; } ``` -------------------------------- ### Recognize Text with Advanced Options Source: https://github.com/kfrancis/ocr/blob/main/tutorial/01_iocrservice_interface_.md This method allows for text recognition from an image byte array using a detailed OcrOptions object for fine-grained control. A CancellationToken is provided for managing the asynchronous operation. ```csharp Task RecognizeTextAsync(byte[] imageData, OcrOptions options, CancellationToken ct = default); ``` -------------------------------- ### Pattern Matching with OcrOptions for Emails Source: https://github.com/kfrancis/ocr/blob/main/tutorial/03_ocroptions_.md Configure OcrOptions with a regex pattern and validation function to extract specific data, such as email addresses, from recognized text. Check and display the matched values. ```csharp var options = new OcrOptions( language: "en", patternConfig: new OcrPatternConfig( regexPattern: @"[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}", validationFunction: email => email.Contains("@") ) ); OcrResult result = await ocrService.RecognizeTextAsync(imageBytes, options); if (result.MatchedValues.Count > 0) { Console.WriteLine("Found email addresses:"); foreach (string email in result.MatchedValues) { Console.WriteLine($" {email}"); } } ``` -------------------------------- ### Configure Custom Text Patterns for OCR Source: https://github.com/kfrancis/ocr/blob/main/tutorial/03_ocroptions_.md Define specific text patterns to search for using regular expressions and optional validation functions. ```csharp public List PatternConfigs { get; } ```