Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@

Microsoft Visual Studio Solution File, Format Version 12.00
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AIServicesDemoApp", "AIServicesDemoApp\AIServicesDemoApp.csproj", "{55EA291C-8258-41B1-8613-721AC04932B3}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Samples", "Samples", "{B9BDE768-2DA1-41ED-9EC6-C5BA2968786C}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "AIServices", "AIServices", "{8FCD2F5B-04E6-4D67-9576-2B0A9F73149F}"
ProjectSection(SolutionItems) = preProject
Samples\AIServices\bbq_receipt.jpg = Samples\AIServices\bbq_receipt.jpg
Samples\AIServices\beer_label.jpg = Samples\AIServices\beer_label.jpg
Samples\AIServices\family.jpg = Samples\AIServices\family.jpg
Samples\AIServices\grunt.jpg = Samples\AIServices\grunt.jpg
Samples\AIServices\loan_application.png = Samples\AIServices\loan_application.png
Samples\AIServices\Photo_alex_prasad.jpg = Samples\AIServices\Photo_alex_prasad.jpg
Samples\AIServices\whole_foods_receipt.jpg = Samples\AIServices\whole_foods_receipt.jpg
Samples\AIServices\paystub.jpg = Samples\AIServices\paystub.jpg
EndProjectSection
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Insurance", "Insurance", "{09FDA3BF-C0E8-4E2C-8F40-663718A461A2}"
ProjectSection(SolutionItems) = preProject
Samples\Insurance\4-Photo_alex.jpg = Samples\Insurance\4-Photo_alex.jpg
Samples\Insurance\1-CMS1500.png = Samples\Insurance\1-CMS1500.png
Samples\Insurance\1-discharge-summary.jpg = Samples\Insurance\1-discharge-summary.jpg
Samples\Insurance\1-drivers_license_alex.jpg = Samples\Insurance\1-drivers_license_alex.jpg
Samples\Insurance\2-insurance_card.jpg = Samples\Insurance\2-insurance_card.jpg
Samples\Insurance\3-discharge-summary.jpg = Samples\Insurance\3-discharge-summary.jpg
Samples\Insurance\3-dr-note-sample.jpg = Samples\Insurance\3-dr-note-sample.jpg
Samples\Insurance\4-id_alex.jpg = Samples\Insurance\4-id_alex.jpg
Samples\Insurance\4-Photo_prasad.jpg = Samples\Insurance\4-Photo_prasad.jpg
Samples\Insurance\insurance_comprehend_train_data.csv = Samples\Insurance\insurance_comprehend_train_data.csv
Samples\Insurance\insurance_invoice.png = Samples\Insurance\insurance_invoice.png
Samples\Insurance\hand-written-note.jpg = Samples\Insurance\hand-written-note.jpg
EndProjectSection
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{55EA291C-8258-41B1-8613-721AC04932B3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{55EA291C-8258-41B1-8613-721AC04932B3}.Debug|Any CPU.Build.0 = Debug|Any CPU
{55EA291C-8258-41B1-8613-721AC04932B3}.Release|Any CPU.ActiveCfg = Release|Any CPU
{55EA291C-8258-41B1-8613-721AC04932B3}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(NestedProjects) = preSolution
{8FCD2F5B-04E6-4D67-9576-2B0A9F73149F} = {B9BDE768-2DA1-41ED-9EC6-C5BA2968786C}
{09FDA3BF-C0E8-4E2C-8F40-663718A461A2} = {B9BDE768-2DA1-41ED-9EC6-C5BA2968786C}
EndGlobalSection
EndGlobal
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<Project Sdk="Microsoft.NET.Sdk.Web">

<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="AWSSDK.Bedrock" Version="3.7.401.3" />
<PackageReference Include="AWSSDK.BedrockRuntime" Version="3.7.401.5" />
<PackageReference Include="AWSSDK.Comprehend" Version="3.7.400.5" />
<PackageReference Include="AWSSDK.Core" Version="3.7.400.5" />
<PackageReference Include="AWSSDK.Extensions.NETCore.Setup" Version="3.7.301" />
<PackageReference Include="AWSSDK.Rekognition" Version="3.7.400.5" />
<PackageReference Include="AWSSDK.S3" Version="3.7.400.5" />
<PackageReference Include="AWSSDK.SecurityToken" Version="3.7.400.5" />
<PackageReference Include="AWSSDK.Textract" Version="3.7.400.5" />
<PackageReference Include="AWSSDK.Translate" Version="3.7.400.5" />
<PackageReference Include="SixLabors.ImageSharp" Version="3.1.5" />
<PackageReference Include="SixLabors.ImageSharp.Drawing" Version="2.1.4" />
</ItemGroup>

</Project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
using Amazon.Runtime.Internal;
using SixLabors.ImageSharp.Processing;
using SixLabors.ImageSharp.Drawing.Processing;
using SixLabors.ImageSharp.PixelFormats;
using SixLabors.ImageSharp;

namespace AIServicesDemoApp;

public class FormDocument
{
public string FileName { get; set; }
public string FileNameWithPath { get; set; }
public MemoryStream MemoryStream { get; set; }
}

public static class Helpers
{
public static string AsBase64String(this MemoryStream memoryStream)
{
return Convert.ToBase64String(memoryStream.ToArray());
}
public static async Task<FormDocument> SaveImage(IFormFile formFile, string webRootPath)
{
var result = new FormDocument();

result.FileName = $"{Guid.NewGuid().ToString()}{System.IO.Path.GetExtension(formFile.FileName)}";
result.FileNameWithPath = System.IO.Path.Combine(webRootPath, "uploads", result.FileName);

await using (var stream = new FileStream(result.FileNameWithPath , FileMode.Create))
{
await formFile.CopyToAsync(stream);
}

result.MemoryStream = new MemoryStream();
await formFile.CopyToAsync(result.MemoryStream);

return result;
}
public static void DrawRectangleUsingBoundingBox(this Image image,
Amazon.Rekognition.Model.BoundingBox boundingBox)
{
// Draw the rectangle using the bounding box values
// They are percentages so scale them to picture
image.Mutate(x => x.DrawLine(
Rgba32.ParseHex("FF0000"),
15,
new PointF[]
{
new PointF(image.Width * boundingBox.Left, image.Height * boundingBox.Top),
new PointF(image.Width * (boundingBox.Left + boundingBox.Width),
image.Height * boundingBox.Top),
new PointF(image.Width * (boundingBox.Left + boundingBox.Width),
image.Height * (boundingBox.Top + boundingBox.Height)),
new PointF(image.Width * boundingBox.Left,
image.Height * (boundingBox.Top + boundingBox.Height)),
new PointF(image.Width * boundingBox.Left, image.Height * boundingBox.Top),
}
));
}

public static void DrawRectangleUsingBoundingBox(this Image image,
Amazon.Textract.Model.BoundingBox boundingBox)
{
// Draw the rectangle using the bounding box values
// They are percentages so scale them to picture
image.Mutate(x => x.DrawLine(
Rgba32.ParseHex("FF0000"),
15,
new PointF[]
{
new PointF(image.Width * boundingBox.Left, image.Height * boundingBox.Top),
new PointF(image.Width * (boundingBox.Left + boundingBox.Width),
image.Height * boundingBox.Top),
new PointF(image.Width * (boundingBox.Left + boundingBox.Width),
image.Height * (boundingBox.Top + boundingBox.Height)),
new PointF(image.Width * boundingBox.Left,
image.Height * (boundingBox.Top + boundingBox.Height)),
new PointF(image.Width * boundingBox.Left, image.Height * boundingBox.Top),
}
));
}
}

public class MyBedrockRequest
{
public List<MyBedrockMessage> messages { get; set; }
public int max_tokens { get; set; } = 500;
public double temperature { get; set; } = 1;
public double top_p { get; set; } = 0.999;
public double top_k { get; set; }
public string anthropic_version { get; set; } = "bedrock-2023-05-31";
public List<string> stop_sequences { get; set; } = ["Human:"];
}
public class MyBedrockMessage
{
public string role { get; set; } = "user";
public List<MyBedrockContent> content { get; set; }
}
public class MyBedrockContent
{
public string type { get; set; } = "text";
public string text { get; set; }
}

public class MyBedrockResponse
{
public string id { get; set; }
public string type { get; set; }
public string role { get; set; }
public List<MyBedrockContent> content { get; set; }
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
@page
@using Microsoft.AspNetCore.Mvc.TagHelpers
@model AnalyzeDocumentModel
@{
ViewData["Title"] = "Analyze Document";
}

<div>
<h2 class="display-4">Analyze Document</h2>

<form method="post" enctype="multipart/form-data">
<div class="form-group">
<label asp-for="FormFile" class="control-label">Document:</label>
<input asp-for="FormFile" class="form-control" type="file" />
</div>
<div class="form-group pt-3">
<input type="submit" class="btn btn-primary" asp-page-handler="DetectText" value="Detect text" />
<input type="submit" class="btn btn-primary" asp-page-handler="DetectTables" value="Detect tables" />
<input type="submit" class="btn btn-primary" asp-page-handler="DetectForms" value="Detect forms" />
</div>
</form>

<div class="container">
<div class="row">
<div class="col-6 pt-3">
@if (!string.IsNullOrEmpty(Model.FileName))
{
<img class="w-100" src="uploads/@Model.FileName" />
}
</div>
<div class="col-6 pt-3">
@Html.Raw(Model.Result)
</div>
</div>
</div>

</div>
Original file line number Diff line number Diff line change
@@ -0,0 +1,165 @@
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using System.Text;
using Amazon.Textract;
using Amazon.Textract.Model;
using SixLabors.ImageSharp;
using SixLabors.ImageSharp.Formats.Jpeg;

namespace AIServicesDemoApp.Pages
{
public class AnalyzeDocumentModel(IAmazonTextract textractClient, IWebHostEnvironment hostEnvironment)
: PageModel
{
[BindProperty]
public IFormFile? FormFile { get; set; }
public string FileName { get; set; } = string.Empty;
public string Result { get; set; } = string.Empty;

public void OnGet()
{
}

public async Task OnPostDetectTextAsync()
{
if (FormFile == null)
{
return;
}
// save document image to display it
var formDocument = await Helpers.SaveImage(FormFile, hostEnvironment.WebRootPath);
FileName = formDocument.FileName;

var detectDocumentTextRequest = new DetectDocumentTextRequest()
{
Document = new Document { Bytes = formDocument.MemoryStream }
};

var detectDocumentTextResponse = await textractClient.DetectDocumentTextAsync(detectDocumentTextRequest);

var stringBuilder = new StringBuilder();

// Load image to modify with face bounding box rectangle
using (var image = await SixLabors.ImageSharp.Image.LoadAsync(formDocument.FileNameWithPath))
{
foreach (var block in detectDocumentTextResponse.Blocks)
{
if (block.BlockType.Value == "LINE")
{
stringBuilder.AppendFormat("{0}<br>", block.Text);

// Get the bounding box
var boundingBox = block.Geometry.BoundingBox;

// Draw the rectangle using the bounding box values
image.DrawRectangleUsingBoundingBox(boundingBox);
}
}

// Save the new image
await image.SaveAsJpegAsync(formDocument.FileNameWithPath, new JpegEncoder { ColorType = JpegEncodingColor.Rgb});
}

Result = stringBuilder.ToString();
}

public async Task OnPostDetectFormsAsync()
{
if (FormFile == null)
{
return;
}
// save document image to display it
var formDocument = await Helpers.SaveImage(FormFile, hostEnvironment.WebRootPath);
FileName = formDocument.FileName;

var analyzeDocumentRequest = new AnalyzeDocumentRequest
{
Document = new Document { Bytes = formDocument.MemoryStream },
FeatureTypes = ["FORMS"]
};

var analyzeDocumentResponse = await textractClient.AnalyzeDocumentAsync(analyzeDocumentRequest);

var stringBuilder = new StringBuilder();

// Load image to modify with face bounding box rectangle
using (var image = await SixLabors.ImageSharp.Image.LoadAsync(formDocument.FileNameWithPath))
{
foreach (var block in analyzeDocumentResponse.Blocks)
{
if (block.BlockType.Value == "KEY_VALUE_SET")
{
foreach (var relation in block.Relationships)
{
if (relation.Type == RelationshipType.CHILD) {
foreach (var id in relation.Ids)
{
var related = analyzeDocumentResponse.Blocks.First(b => b.Id == id);

stringBuilder.AppendFormat("{0} ", related.Text);
}
}

stringBuilder.AppendFormat("<br>");
}

// Get the bounding box
var boundingBox = block.Geometry.BoundingBox;

// Draw the rectangle using the bounding box values
image.DrawRectangleUsingBoundingBox(boundingBox);
}
}

// Save the new image
await image.SaveAsJpegAsync(formDocument.FileNameWithPath, new JpegEncoder { ColorType = JpegEncodingColor.Rgb});
}

Result = stringBuilder.ToString();
}

public async Task OnPostDetectTablesAsync()
{
if (FormFile == null)
{
return;
}
// save document image to display it
var formDocument = await Helpers.SaveImage(FormFile, hostEnvironment.WebRootPath);
FileName = formDocument.FileName;

var analyzeDocumentRequest = new AnalyzeDocumentRequest
{
Document = new Document { Bytes = formDocument.MemoryStream },
FeatureTypes = ["TABLES"]
};

var analyzeDocumentResponse = await textractClient.AnalyzeDocumentAsync(analyzeDocumentRequest);

var stringBuilder = new StringBuilder();

// Load image to modify with face bounding box rectangle
using (var image = await SixLabors.ImageSharp.Image.LoadAsync(formDocument.FileNameWithPath))
{
foreach (var block in analyzeDocumentResponse.Blocks)
{
if (block.BlockType.Value == "TABLE")
{
// Get the bounding box
var boundingBox = block.Geometry.BoundingBox;

// Draw the rectangle using the bounding box values
image.DrawRectangleUsingBoundingBox(boundingBox);
}
}

// Save the new image
await image.SaveAsJpegAsync(formDocument.FileNameWithPath, new JpegEncoder { ColorType = JpegEncodingColor.Rgb});
}

Result = stringBuilder.ToString();
}

}
}
Loading