1- using ClassifiedAds . Application . FileEntries . MessageBusEvents ;
1+ using Azure ;
2+ using Azure . AI . Vision . ImageAnalysis ;
3+ using ClassifiedAds . Application . FileEntries . MessageBusEvents ;
24using ClassifiedAds . Domain . Entities ;
35using ClassifiedAds . Domain . Infrastructure . Messaging ;
46using ClassifiedAds . Domain . Infrastructure . Storages ;
911using Microsoft . Extensions . Logging ;
1012using System ;
1113using System . IO ;
14+ using System . Linq ;
1215using System . Net . Http ;
1316using System . Net . Http . Headers ;
1417using System . Security . Cryptography ;
18+ using System . Text . Json ;
1519using System . Threading ;
1620using System . Threading . Tasks ;
1721
@@ -77,9 +81,9 @@ private async Task ProcessFileAsync(FileEntry fileEntry, CancellationToken cance
7781 // TODO: xxx
7882 return ;
7983 }
80-
81- if ( fileExtension == ".pdf " ||
82- fileExtension == ".docx " )
84+ else if ( fileExtension == ".pdf" ||
85+ fileExtension == ".docx " ||
86+ fileExtension == ".pptx " )
8387 {
8488 _logger . LogInformation ( "Converting file to markdown for FileEntry Id: {FileEntryId}" , fileEntry ? . Id ) ;
8589
@@ -98,9 +102,30 @@ private async Task ProcessFileAsync(FileEntry fileEntry, CancellationToken cance
98102 await File . WriteAllTextAsync ( markdownFile , markdown , cancellationToken ) ;
99103 }
100104 }
105+ else if ( fileExtension == ".jpg" ||
106+ fileExtension == ".png" )
107+ {
108+ _logger . LogInformation ( "Processing image file for FileEntry Id: {FileEntryId}" , fileEntry ? . Id ) ;
109+
110+ var imageAnalysisFolder = Path . Combine ( _configuration [ "Storage:TempFolderPath" ] , "ImageAnalysis" ) ;
111+
112+ if ( ! Directory . Exists ( imageAnalysisFolder ) )
113+ {
114+ Directory . CreateDirectory ( imageAnalysisFolder ) ;
115+ }
116+
117+ var imageAnalysisFile = Path . Combine ( imageAnalysisFolder , fileEntry . Id + ".json" ) ;
118+
119+ if ( ! File . Exists ( imageAnalysisFile ) )
120+ {
121+ var imageAnalysisResult = await AnalyzeImageAsync ( fileStorageManager , fileEntry , cancellationToken ) ;
122+
123+ await File . WriteAllTextAsync ( imageAnalysisFile , JsonSerializer . Serialize ( imageAnalysisResult ) , cancellationToken ) ;
124+ }
125+ }
101126 }
102127
103- private async Task < string > ConvertToMarkdownAsync ( IFileStorageManager fileStorageManager , FileEntry fileEntry , CancellationToken cancellationToken = default )
128+ private async Task < byte [ ] > GetBytesAsync ( IFileStorageManager fileStorageManager , FileEntry fileEntry , CancellationToken cancellationToken )
104129 {
105130 var content = await fileStorageManager . ReadAsync ( fileEntry , cancellationToken ) ;
106131
@@ -124,6 +149,13 @@ private async Task<string> ConvertToMarkdownAsync(IFileStorageManager fileStorag
124149 : content ;
125150 }
126151
152+ return content ;
153+ }
154+
155+ private async Task < string > ConvertToMarkdownAsync ( IFileStorageManager fileStorageManager , FileEntry fileEntry , CancellationToken cancellationToken = default )
156+ {
157+ var content = await GetBytesAsync ( fileStorageManager , fileEntry , cancellationToken ) ;
158+
127159 using var form = new MultipartFormDataContent ( ) ;
128160 using var fileContent = new ByteArrayContent ( content ) ;
129161 fileContent . Headers . ContentType = MediaTypeHeaderValue . Parse ( "multipart/form-data" ) ;
@@ -137,4 +169,68 @@ private async Task<string> ConvertToMarkdownAsync(IFileStorageManager fileStorag
137169
138170 return markdown ;
139171 }
172+
173+ private ImageAnalysisClient CreateImageAnalysisClient ( string endpoint , string key )
174+ {
175+ var client = new ImageAnalysisClient ( new Uri ( endpoint ) , new AzureKeyCredential ( key ) ) ;
176+ return client ;
177+ }
178+
179+ private async Task < ImageAnalysisResult > AnalyzeImageAsync ( IFileStorageManager fileStorageManager , FileEntry fileEntry , CancellationToken cancellationToken = default )
180+ {
181+ string key = _configuration [ "ImageAnalysis:AzureAIVision:ApiKey" ] ! ;
182+ string endpoint = _configuration [ "ImageAnalysis:AzureAIVision:Endpoint" ] ! ;
183+
184+ // Create a client
185+ var client = CreateImageAnalysisClient ( endpoint , key ) ;
186+ var bytes = await GetBytesAsync ( fileStorageManager , fileEntry , cancellationToken ) ;
187+
188+ // Creating a list that defines the features to be extracted from the image.
189+ VisualFeatures features = VisualFeatures . Caption | VisualFeatures . DenseCaptions | VisualFeatures . Tags ;
190+
191+ // Analyze the image
192+ var result = await client . AnalyzeAsync ( new BinaryData ( bytes ) , visualFeatures : features , cancellationToken : cancellationToken ) ;
193+
194+ return new ImageAnalysisResult
195+ {
196+ Tags = result . Value . Tags . Values . Select ( x => new Tag
197+ {
198+ Name = x . Name ,
199+ Confidence = x . Confidence
200+ } ) . ToArray ( ) ,
201+ Caption = new Caption
202+ {
203+ Text = result . Value . Caption . Text ,
204+ Confidence = result . Value . Caption . Confidence
205+ } ,
206+ DenseCaptions = result . Value . DenseCaptions . Values . Select ( x => new Caption
207+ {
208+ Text = x . Text ,
209+ Confidence = x . Confidence
210+ } ) . ToArray ( )
211+ } ;
212+ }
213+
214+ class ImageAnalysisResult
215+ {
216+ public Tag [ ] Tags { get ; set ; }
217+
218+ public Caption Caption { get ; set ; }
219+
220+ public Caption [ ] DenseCaptions { get ; set ; }
221+ }
222+
223+ class Tag
224+ {
225+ public string Name { get ; set ; }
226+
227+ public float Confidence { get ; set ; }
228+ }
229+
230+ class Caption
231+ {
232+ public string Text { get ; set ; }
233+
234+ public float Confidence { get ; set ; }
235+ }
140236}
0 commit comments