-
Notifications
You must be signed in to change notification settings - Fork 2
/
AzureOpenAIVisionDocumentDataExtractor.cs
78 lines (62 loc) · 2.76 KB
/
AzureOpenAIVisionDocumentDataExtractor.cs
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
using System.Globalization;
using Azure.AI.OpenAI;
using EvaluationTests.Shared.Storage;
using SkiaSharp;
namespace EvaluationTests.Shared.Extraction.AzureOpenAI;
public class AzureOpenAIVisionDocumentDataExtractor(
OpenAIClient client,
ChatCompletionsOptions chatCompletionOptions,
TestOutputStorage? outputStorage = null) :
AzureOpenAIDocumentDataExtractor(client, chatCompletionOptions, outputStorage)
{
public override async Task<DataExtractionResult> FromDocumentBytesAsync(byte[] documentBytes,
CancellationToken cancellationToken = default)
{
var images = await ToProcessedImages(documentBytes);
var imagePromptItems = new List<ChatMessageContentItem>();
imagePromptItems.AddRange(images.Select(image =>
new ChatMessageImageContentItem(BinaryData.FromBytes(image), "image/jpeg")));
return await GetChatCompletionsAsync(new ChatRequestUserMessage(imagePromptItems.ToArray()));
}
private async Task<IEnumerable<byte[]>> ToProcessedImages(byte[] documentBytes)
{
var pageImages = PDFtoImage.Conversion.ToImages(documentBytes);
var totalPageCount = pageImages.Count();
// Group images if the total page count is too large.
var maxSize = (int)Math.Ceiling(totalPageCount / 25.0);
var pageImageGroups = new List<List<SKBitmap>>();
for (var i = 0; i < totalPageCount; i += maxSize)
{
var pageImageGroup = pageImages.Skip(i).Take(maxSize).ToList();
pageImageGroups.Add(pageImageGroup);
}
var pdfImageFiles = new List<byte[]>();
// Stitch images together if they have been grouped.
foreach (var pageImageGroup in pageImageGroups)
{
var totalHeight = pageImageGroup.Sum(image => image.Height);
var width = pageImageGroup.Max(image => image.Width);
var stitchedImage = new SKBitmap(width, totalHeight);
var canvas = new SKCanvas(stitchedImage);
var currentHeight = 0;
foreach (var pageImage in pageImageGroup)
{
canvas.DrawBitmap(pageImage, 0, currentHeight);
currentHeight += pageImage.Height;
}
var stitchedImageStream = new MemoryStream();
stitchedImage.Encode(stitchedImageStream, SKEncodedImageFormat.Jpeg, 100);
pdfImageFiles.Add(stitchedImageStream.ToArray());
}
if (OutputStorage == null)
{
return pdfImageFiles;
}
for (var i = 0; i < pdfImageFiles.Count; i++)
{
await OutputStorage.SaveBytesAsync(pdfImageFiles[i],
$"{DateTime.UtcNow.ToString("yy-MM-dd", CultureInfo.InvariantCulture)}.Page-{i}.jpg");
}
return pdfImageFiles;
}
}