logo
Exploring Amazon Rekognition and Textract in .NET Blazor

Exploring Amazon Rekognition and Textract in .NET Blazor

Let's learn Amazon Rekognition and Amazon Textract in .NET Blazor

Published Feb 11, 2024

Have you ever heard about Amazon Rekognition and Amazon Textract? Please read these pages:
We will explore Amazon Rekognition, which will help us recognize images and analyze videos with machine learning (ML). Amazon Rekognition has the ML models to do their tasks, so we don't have to worry! In addition, we will explore Amazon Textract, which will help us extract printed text, handwriting, etc.

Please prepare some of these tools:
  1. Your favorite IDE.
  2. .NET SDK
  3. AWS Account (of course, you will need an AWS Account)
  4. That's all. :)
I use Visual Studio 2022 Community Edition, so feel free to use another IDE.

  • You may click "Create a new project".
Create project
Create project
  • Search "blazor" and select "Blazor Web App". Click Next.
Blazor Search
Blazor Search
  • Feel free to give any project names and select the project directory. Click Next.
Project Directory
Project Directory
  • I use the default value. Feel free to modify the options. Click Create.
Default
Default

You may use this command: dotnet new blazorserver -o RekognitionTextractExploration.

  • Right-click on the Project and click Manage NuGet Packages...
Right click project
Right click project
  • Click Browse, search Rekognition, click AWSSDK.Rekognition, click Install.
Rekognition Install
Rekognition Install
  • Search Textract, and click AWSSDK.Textract, click Install.
Install textract
Install textract

You may use these commands:
  • dotnet add RekognitionTextractExploration package AWSSDK.Rekognition
  • dotnet add RekognitionTextractExploration package AWSSDK.Textract

  • You can right-click on the Pages directory. You may locate the Pages directory under the Components directory. Select Add > New Item. Click on Razor Component and give any appropriate name, for example, DetectLabels. We will learn to detect labels from a picture which is a feature that Amazon Rekognition has.
  • You may copy-paste this code to DetectLabels.razor.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
@page "/detect-labels"
@rendermode InteractiveServer
@using System
@using System.IO
@using Microsoft.AspNetCore.Hosting
@using Amazon
@using Amazon.Rekognition
@using Amazon.Rekognition.Model
@inject ILogger<DetectLabels> Logger
@inject IWebHostEnvironment Environment

<h3>Detect Labels</h3>

<InputFile OnChange="@LoadFiles" />

@if(isGenerateResult)
{
<p>Generating result...</p>
}

@if(!string.IsNullOrEmpty(ErrorMessage))
{
<p>@ErrorMessage</p>
}

@foreach(var result in results)
{
<p>@result</p>
}

@code {
private long maxFileSize = 1024 * 1024 * 1024;
private AmazonRekognitionClient? _rekognitionClient;
private List<string> results = new List<string>();
private bool isGenerateResult = false;
private string ErrorMessage = string.Empty;

protected override void OnInitialized()
{
_rekognitionClient = new AmazonRekognitionClient(RegionEndpoint.APSoutheast1);
}

private async Task LoadFiles(InputFileChangeEventArgs e)
{
if (_rekognitionClient == null)
{
return;
}
var files = e.GetMultipleFiles(1);
if (files.Count != 1)
{
return;
}
var isError = false;
try
{

isGenerateResult = true;
var file = files[0];
var trustedFileName = Path.GetTempFileName();

var image = new Image();

using (var fs = new FileStream(trustedFileName, FileMode.Create))
{
await file.OpenReadStream(maxFileSize).CopyToAsync(fs);
}
using var readFs = new FileStream(trustedFileName, FileMode.Open, FileAccess.Read);

byte[] data = null;
data = new byte[readFs.Length];
readFs.Read(data, 0, (int)readFs.Length);
image.Bytes = new MemoryStream(data);

DetectLabelsRequest detectlabelsRequest = new DetectLabelsRequest()
{
Image = image,
MaxLabels = 10,
MinConfidence = 75F
};
Logger.LogInformation($"Detecting labels for {trustedFileName}");
var detectLabelsResponse = await _rekognitionClient.DetectLabelsAsync(detectlabelsRequest);
Logger.LogInformation($"Detected labels for {trustedFileName}");
results.Clear();
foreach (var label in detectLabelsResponse.Labels)
{
var message = $"Label: {label.Name}, Confidence: {label.Confidence}";
Logger.LogInformation(message);
results.Add(message);
}
}
catch (Exception ex)
{
Logger.LogError(ex, "Something wrong");
ErrorMessage = ex.ToString();
isError = true;
}

if (!isError)
{
ErrorMessage = string.Empty;
}

isGenerateResult = false;
}
}
  • To add the navigation, please add these codes in NavMenu.razor. You may find the file under Components > Layout directory.
1
2
3
4
5
<div class="nav-item px-3">
<NavLink class="nav-link" href="detect-labels">
<span class="bi bi-list-nested-nav-menu" aria-hidden="true"></span> Detect Labels
</NavLink>
</div>
  • Your NavMenu.razor will be like this.
Razor result
Razor result

There are three important steps. Let's check it out!
  1. The user will upload the file to the server. We will store the file in the temporary directory.
  2. We will read the file as a stream and send that to DetectLabelsAsync.
  3. After getting the result, we will add the detected labels to the results variable.

  • Create a new Blazor Page for exploring Amazon Textract, for example, Textract.razor.
  • You may copy-paste these codes.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
@page "/detect-text"
@rendermode InteractiveServer
@using System
@using System.IO
@using Microsoft.AspNetCore.Hosting
@using Amazon
@using Amazon.Textract
@using Amazon.Textract.Model
@inject ILogger<DetectLabels> Logger
@inject IWebHostEnvironment Environment

<h3>Detect Texts</h3>

<InputFile OnChange="@LoadFiles" />

@if (isGenerateResult)
{
<p>Generating result...</p>
}

@if (!string.IsNullOrEmpty(ErrorMessage))
{
<p>@ErrorMessage</p>
}

@foreach (var result in results)
{
<p>@result</p>
}

@code {
private long maxFileSize = 1024 * 1024 * 1024;
private AmazonTextractClient? _textractClient;
private List<string> results = new List<string>();
private bool isGenerateResult = false;
private string ErrorMessage = string.Empty;

protected override void OnInitialized()
{
_textractClient = new AmazonTextractClient(RegionEndpoint.APSoutheast1);
}

private async Task LoadFiles(InputFileChangeEventArgs e)
{
if (_textractClient == null)
{
return;
}
var files = e.GetMultipleFiles(1);
if (files.Count != 1)
{
return;
}
var isError = false;
try
{

isGenerateResult = true;
var file = files[0];
var trustedFileName = Path.GetTempFileName();

var doc = new Document();

using (var fs = new FileStream(trustedFileName, FileMode.Create))
{
await file.OpenReadStream(maxFileSize).CopyToAsync(fs);
}
using var readFs = new FileStream(trustedFileName, FileMode.Open, FileAccess.Read);

byte[] data = null;
data = new byte[readFs.Length];
readFs.Read(data, 0, (int)readFs.Length);
doc.Bytes = new MemoryStream(data);

DetectDocumentTextRequest detectText = new DetectDocumentTextRequest()
{
Document = doc,
};
Logger.LogInformation($"Detecting text for {trustedFileName}");
var detectTextResponse = await _textractClient.DetectDocumentTextAsync(detectText);
Logger.LogInformation($"Detected text for {trustedFileName}");
results.Clear();
foreach (var block in detectTextResponse.Blocks)
{
var message = $"Text: {block.Text}, Block Type: {block.BlockType}, Confidence: {block.Confidence}";
Logger.LogInformation(message);
results.Add(message);
}
}
catch (Exception ex)
{
Logger.LogError(ex, "Something wrong");
ErrorMessage = ex.ToString();
isError = true;
}

if (!isError)
{
ErrorMessage = string.Empty;
}

isGenerateResult = false;
}
}
  • To add the navigation, please add these codes in NavMenu.razor.
1
2
3
4
5
<div class="nav-item px-3">
<NavLink class="nav-link" href="detect-text">
<span class="bi bi-list-nested-nav-menu" aria-hidden="true"></span> Detect Text
</NavLink>
</div>

There are three important steps. Let's check it out!
  1. The user will upload the file to the server. We will store the file in the temporary directory.
  2. We will read the file as a stream and send that to DetectDocumentTextAsync.
  3. After getting the result, we will add the detected texts to the results variable.

Those features are cool, right? I only share a feature from each service, you may explore other features as well. If you have any feedback, feel free to share it with me. Please take a look at my repository here.
Thank you
Thank you
Image by katemangostar on Freepik