.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
*.mobileprovisionfile and copy it to the~/Library/MobileDevice/Provisioning Profilesfolder.
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.0tonet8.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
.csprojfile and change theTargetFrameworkvalue fromnet7.0tonet8.0. -
Add
<SupportedOSPlatformVersion>to thePropertyGroupelement to ensure compatibility:
<PropertyGroup Condition="$(TargetFramework.Contains('-ios'))"> <SupportedOSPlatformVersion>11.0</SupportedOSPlatformVersion> </PropertyGroup>
Adding a Round Button for Document Capture
-
Update the
CameraPage.xamlfile 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
OnCaptureButtonClickedevent handler in theCameraPage.xaml.csfile:
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
isReadyflag in theOnAppearingevent handler:
protected override async void OnAppearing() { base.OnAppearing(); isReady = false; ... }
Sharing the Normalized Document
-
In the
ImagePage.xamlfile, add aToolbarItemas 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
OnShareButtonClickedevent handler in theImagePage.xaml.csfile:
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
_itemvariable stores the normalized image data. After assigning the image data to theImagecontrol,image.Sourceis not directly available for image operations. - To share the image, save it as a temporary file and use the
Share.RequestAsyncmethod to share the file.
- The
Running the .NET MAUI Document Scanner
-
In Visual Studio Code, press
F1to 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


Top comments (0)