diff --git a/Configurations/XAiApiConfiguration.cs b/Configurations/XAiApiConfiguration.cs index 323c1bf..32a2418 100644 --- a/Configurations/XAiApiConfiguration.cs +++ b/Configurations/XAiApiConfiguration.cs @@ -1,3 +1,4 @@ +using xAiApi.Models; using xAiModels.Models; namespace xAiApi.Configurations @@ -13,5 +14,10 @@ namespace xAiApi.Configurations /// Allowed Prompts to Use ... /// public XAiPromptDescriptor[] Prompts { get; set; } = []; + + /// + /// OCR Configuration ... + /// + public XAiOCRDescriptor OCR { get; set; } } } \ No newline at end of file diff --git a/Models/XAiOCRDescriptor.cs b/Models/XAiOCRDescriptor.cs new file mode 100644 index 0000000..1554ff0 --- /dev/null +++ b/Models/XAiOCRDescriptor.cs @@ -0,0 +1,27 @@ +using Tesseract; + +namespace xAiApi.Models +{ + public class XAiOCRDescriptor + { + /// + /// Provides Trained Data Path ... + /// + public string DataPath { get; set; } + + /// + /// The Engine for Doing OCR ... + /// + public EngineMode EngineMode { get; set; } + + /// + /// Enable OCR Fallback using Model ... + /// + public bool EnableOcrFallback { get; set; } + + /// + /// Default OCR Language ... + /// + public string DefaultLanguage { get; set; } + } +} \ No newline at end of file diff --git a/Providers/Extractors/XImageFileContentExtractor.cs b/Providers/Extractors/XImageFileContentExtractor.cs index 042eefd..2578e52 100644 --- a/Providers/Extractors/XImageFileContentExtractor.cs +++ b/Providers/Extractors/XImageFileContentExtractor.cs @@ -5,6 +5,10 @@ using System.Threading; using xAiModels.Models; using System.Threading.Tasks; using xAiApi.Interfaces.Extractors; +using xAiApi.Configurations; +using xCommons.Extensions; +using xExceptions.Constants; +using Tesseract; namespace xAiApi.Providers.Extractors { @@ -24,16 +28,25 @@ namespace xAiApi.Providers.Extractors ]; /// - /// آیا OCR فعال است (برای مدل‌های غیر Vision) ... + /// AI Api Configuration ... /// - private readonly bool _enableOcrFallback; + private readonly XAiApiConfiguration configuration; - public XImageFileContentExtractor() : this(enableOcrFallback: true) - { } - - public XImageFileContentExtractor(bool enableOcrFallback = true) + public XImageFileContentExtractor( + XAiApiConfiguration configuration + ) { - _enableOcrFallback = enableOcrFallback; + // + if (configuration.IsNullOrDefault() || + configuration.OCR.IsNullOrDefault() || + configuration.OCR.DataPath.IsNullOrEmpty() || + configuration.OCR.DefaultLanguage.IsNullOrEmpty()) + { + XException.InvalidConfiguration.Throw(); + } + + // + this.configuration = configuration; } /// @@ -103,8 +116,9 @@ namespace xAiApi.Providers.Extractors Description = $"Attached image: {fileName}" }); - // OCR Fallback برای مدل‌های متنی - if (_enableOcrFallback) + // + // OCR Fallback ... + if (configuration.OCR.EnableOcrFallback) { // try @@ -135,8 +149,44 @@ namespace xAiApi.Providers.Extractors ) { // - // TODO: Complete this ... - return await Task.FromResult(string.Empty); + return await Task.Run(() => + { + // + // Validate Path ... + if (!Directory.Exists(configuration.OCR.DataPath)) + { + // + throw new DirectoryNotFoundException( + $"TessData directory not found at: {configuration.OCR.DataPath}. " + + "Please download traineddata files from https://github.com/tesseract-ocr/tessdata" + ); + } + + // + using var engine = new TesseractEngine( + datapath: configuration.OCR.DataPath, + language: configuration.OCR.DefaultLanguage, + engineMode: configuration.OCR.EngineMode + ); + + // + using var pix = Pix.LoadFromMemory(imageBytes); + + // + cancellationToken.ThrowIfCancellationRequested(); + + // + using var page = engine.Process(pix); + + // + var text = page.GetText(); + + // + text = text?.Trim(); + + // + return text ?? string.Empty; + }, cancellationToken); } } } \ No newline at end of file diff --git a/Startup.cs b/Startup.cs index 139a696..15c7f94 100644 --- a/Startup.cs +++ b/Startup.cs @@ -199,14 +199,6 @@ namespace xAiApi // services.AddSingleton(); - // services.AddSingleton(sp => - // { - // // - // var extractors = sp.GetServices(); - // return new XFileContentExtractor(extractors); - // }); - // services.AddSingleton(sp => - // sp.GetRequiredService()); // // Register Default Ai Service ... diff --git a/appsettings.Development.json b/appsettings.Development.json index 5ed4b88..cfd8ad5 100644 --- a/appsettings.Development.json +++ b/appsettings.Development.json @@ -78,12 +78,18 @@ "Description": "", "Params": [] } - ] + ], + "OCR": { + "DataPath": "Models", + "EngineMode": "LstmOnly", + "EnableOcrFallback": true, + "DefaultLanguage": "fas+eng" + } }, "Logging": { "LogLevel": { - "Default": "Information", "Microsoft": "Warning", + "Default": "Information", "Microsoft.Hosting.Lifetime": "Information" } },