Creating a .NET MAUI Document Scanner: Capture, Normalize, and Share Documents Effortlessly
Xiao Ling
Posted on November 6, 2024
.NET MAUI simplifies cross-platform app development by enabling a single codebase for multiple platforms. The Dynamsoft Capture Vision MAUI Bundle offers powerful APIs for document scanning, barcode reading, and MRZ recognition. In this tutorial, you’ll learn how to create a .NET MAUI document scanner that can capture, normalize, and share documents on both Android and iOS platforms.
.NET MAUI Document Scanner Demo Video
Prerequisites
To get started, ensure you have the following tools installed:
- Dynamsoft Capture Vision Trial License
- Xcode
- Android Studio
- Visual Studio for Windows or Visual Studio Code for macOS with the .NET MAUI extension
- Provisioning Profile for iOS (required if building a .NET MAUI app with Visual Studio Code on macOS):
- Log into your Apple Developer account.
- Navigate to Certificates, Identifiers & Profiles to create an App ID and Provisioning Profile.
- Download the
*.mobileprovision
file and copy it to the~/Library/MobileDevice/Provisioning Profiles
folder.
Building a .NET MAUI Document Scanner Step by Step
Dynamsoft provides a .NET MAUI sample project demonstrating how to automatically capture and normalize documents from a camera stream. Based on this sample, we’ll make a few modifications:
- Update the target framework from
net7.0
tonet8.0
. - Add a button to trigger document capture and rectification.
- Allow users to share the normalized document to other apps.
Updating the .NET MAUI Project from .NET 7 to .NET 8
The latest .NET version is 8.0, while the sample project uses .NET 7.0. To update the target framework:
- Open the
.csproj
file and change theTargetFramework
value fromnet7.0
tonet8.0
. -
Add
<SupportedOSPlatformVersion>
to thePropertyGroup
element to ensure compatibility:
<PropertyGroup Condition="$(TargetFramework.Contains('-ios'))"> <SupportedOSPlatformVersion>11.0</SupportedOSPlatformVersion> </PropertyGroup>
Adding a Round Button for Document Capture
-
Update the
CameraPage.xaml
file to add a round button for document capture:
<?xml version="1.0" encoding="utf-8" ?> <ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" xmlns:controls="clr-namespace:Dynamsoft.CameraEnhancer.Maui;assembly=Dynamsoft.CameraEnhancer.Maui" x:Class="AutoNormalize.CameraPage" Title="Auto Normalize"> <AbsoluteLayout> <controls:CameraView x:Name="camera" AbsoluteLayout.LayoutBounds="0,0,1,1" AbsoluteLayout.LayoutFlags="All"/> <!-- Capture Button --> <Button x:Name="captureButton" BackgroundColor="White" WidthRequest="70" HeightRequest="70" CornerRadius="35" Clicked="OnCaptureButtonClicked" HorizontalOptions="Center" VerticalOptions="End" AbsoluteLayout.LayoutBounds="0.5, 0.9, 90, 90" AbsoluteLayout.LayoutFlags="PositionProportional"/> </AbsoluteLayout> </ContentPage>
-
Implement the
OnCaptureButtonClicked
event handler in theCameraPage.xaml.cs
file:
bool isReady = false; private void OnCaptureButtonClicked(object sender, EventArgs e) { isReady = true; } public void OnNormalizedImagesReceived(NormalizedImagesResult result) { if (result?.Items?.Count > 0 && isReady) { router?.StopCapturing(); enhancer?.ClearBuffer(); var data = result.Items[0].ImageData; MainThread.BeginInvokeOnMainThread(async () => { await Navigation.PushAsync(new ImagePage(data)); }); } }
-
Reset the
isReady
flag in theOnAppearing
event handler:
protected override async void OnAppearing() { base.OnAppearing(); isReady = false; ... }
Sharing the Normalized Document
-
In the
ImagePage.xaml
file, add aToolbarItem
as a share button:
<?xml version="1.0" encoding="utf-8" ?> <ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" x:Class="AutoNormalize.ImagePage" Title="ImagePage"> <!-- Toolbar Item for Share Button --> <ContentPage.ToolbarItems> <ToolbarItem Text="Share" Order="Primary" Priority="0" Clicked="OnShareButtonClicked"/> </ContentPage.ToolbarItems> <Grid RowDefinitions="Auto, *, Auto" ColumnDefinitions="*,*,*"> <Button Text="gray" Grid.Row="0" Grid.Column="0" Margin="10,20" Clicked="OnButtonClicked"/> <Button Text="color" Grid.Row="0" Grid.Column="1" Margin="10,20" Clicked="OnButtonClicked"/> <Button Text="binary" Grid.Row="0" Grid.Column="2" Margin="10,20" Clicked="OnButtonClicked"/> <Image x:Name="image" Grid.Row="1" Grid.ColumnSpan="3" Margin="20,0,20,20"/> </Grid> </ContentPage>
-
Implement the
OnShareButtonClicked
event handler in theImagePage.xaml.cs
file:
private void normalize(EnumImageColourMode type) { var name = EnumPresetTemplate.PT_NORMALIZE_DOCUMENT; var settings = cvr.GetSimplifiedSettings(name); settings.DocumentSettings.ColourMode = type; cvr.UpdateSettings(name, settings); var result = cvr.Capture(data, name); if (result?.Items?.Count > 0 && result.Items[0].Type == EnumCapturedResultItemType.CRIT_NORMALIZED_IMAGE) { _item = (NormalizedImageResultItem)result.Items[0]; image.Source = _item.ImageData.ToImageSource(); } } private async void OnShareButtonClicked(object sender, EventArgs e) { if (_item == null) { await DisplayAlert("Error", "Image is not shareable.", "OK"); return; } var imageSource = _item.ImageData.ToImageSource(); if (imageSource is StreamImageSource streamImageSource) { var stream = await streamImageSource.Stream(CancellationToken.None); var tempFile = Path.Combine(FileSystem.CacheDirectory, "shared_image.jpg"); using (var memoryStream = new MemoryStream()) { await stream.CopyToAsync(memoryStream); await File.WriteAllBytesAsync(tempFile, memoryStream.ToArray()); } await Share.RequestAsync(new ShareFileRequest { Title = "Share Image", File = new ShareFile(tempFile) }); } else { await DisplayAlert("Error", "Image is not shareable.", "OK"); } }
Explanation
- The
_item
variable stores the normalized image data. After assigning the image data to theImage
control,image.Source
is not directly available for image operations. - To share the image, save it as a temporary file and use the
Share.RequestAsync
method to share the file.
- The
Running the .NET MAUI Document Scanner
-
In Visual Studio Code, press
F1
to open the command palette and pick a target device to run the app. -
Capture and normalize a document, then share it with other apps.
Source Code
https://github.com/yushulx/maui-barcode-mrz-document-scanner/tree/main/examples/DocumentScanner
Posted on November 6, 2024
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.
Related
November 6, 2024