2025-01-28 13:10:49 -03:00
using Newtonsoft.Json ;
using System ;
using System.Collections.Generic ;
using System.IO ;
using System.Linq ;
using System.Net.Http ;
using System.Text ;
using System.Threading.Tasks ;
namespace GTPCorrgir
{
public class OcrTextProcessor : IDisposable
{
private readonly HttpClient _httpClient ;
private string _openAiApiKey ;
private bool _disposed ;
public OcrTextProcessor ( )
{
_httpClient = new HttpClient ( ) ;
InitializeProcessor ( ) ;
}
private void InitializeProcessor ( )
{
try
{
LoadApiKey ( ) ;
InitializeHttpClient ( ) ;
}
catch ( Exception ex )
{
throw new ApplicationException ( "Error initializing OCR Text Processor" , ex ) ;
}
}
private void LoadApiKey ( )
{
string configPath = Path . Combine ( AppDomain . CurrentDomain . BaseDirectory , "appsettings.json" ) ;
if ( ! File . Exists ( configPath ) )
{
throw new FileNotFoundException ( "Configuration file (appsettings.json) not found." ) ;
}
string jsonContent = File . ReadAllText ( configPath ) ;
var settings = JsonConvert . DeserializeObject < ApiSettings > ( jsonContent ) ;
_openAiApiKey = settings ? . ApiKeys ? . OpenAI ;
if ( string . IsNullOrEmpty ( _openAiApiKey ) )
{
throw new ApplicationException ( "OpenAI API key is missing" ) ;
}
}
private void InitializeHttpClient ( )
{
_httpClient . Timeout = TimeSpan . FromSeconds ( 30 ) ;
_httpClient . DefaultRequestHeaders . Clear ( ) ;
_httpClient . DefaultRequestHeaders . Add ( "Accept" , "application/json" ) ;
}
public async Task < string > ProcessOcrText ( string ocrText )
{
try
{
// Correct OCR errors using LLM
2025-01-31 07:49:56 -03:00
string correctedText = await CorrectOcrErrors ( ocrText ) ;
//string correctedText = ocrText;
2025-01-28 13:10:49 -03:00
// Apply minimal markdown formatting
string formattedText = ApplyBasicFormatting ( correctedText ) ;
// Copiar al portapapeles usando ClipboardHelper
await ClipboardHelper . SetText ( formattedText ) ;
return formattedText ;
}
catch ( Exception ex )
{
throw new ApplicationException ( "Error processing OCR text" , ex ) ;
}
}
private async Task < string > CorrectOcrErrors ( string text )
{
try
{
_httpClient . DefaultRequestHeaders . Clear ( ) ;
_httpClient . DefaultRequestHeaders . Add ( "Authorization" , $"Bearer {_openAiApiKey}" ) ;
var requestData = new
{
model = "gpt-4" ,
messages = new [ ]
{
new {
role = "system" ,
content = "You are an expert at correcting OCR errors. Fix common OCR mistakes like: confused characters (0/O, l/I, rn/m), broken words, and formatting issues. Preserve the original structure and meaning. Respond only with the corrected text in JSON format: {\"corrected_text\": \"your text here\"}"
} ,
new {
role = "user" ,
content = $"Please correct any OCR errors in this text: {text}"
}
}
} ;
var content = new StringContent (
JsonConvert . SerializeObject ( requestData ) ,
Encoding . UTF8 ,
"application/json"
) ;
using var response = await _httpClient . PostAsync ( "https://api.openai.com/v1/chat/completions" , content ) ;
var responseContent = await response . Content . ReadAsStringAsync ( ) ;
if ( ! response . IsSuccessStatusCode )
{
throw new HttpRequestException ( $"Error calling OpenAI API: {response.StatusCode} - {responseContent}" ) ;
}
var responseData = JsonConvert . DeserializeObject < dynamic > ( responseContent ) ;
string correctedText = responseData . choices [ 0 ] . message . content ;
// Extract the actual text from the JSON response
var jsonResponse = JsonConvert . DeserializeObject < dynamic > ( correctedText ) ;
return jsonResponse . corrected_text . ToString ( ) ;
}
catch ( Exception ex )
{
throw new ApplicationException ( "Error correcting OCR text" , ex ) ;
}
}
private string ApplyBasicFormatting ( string text )
{
var lines = text . Split ( '\n' ) ;
var result = new StringBuilder ( ) ;
for ( int i = 0 ; i < lines . Length ; i + + )
{
string currentLine = lines [ i ] . Trim ( ) ;
// Skip empty lines
if ( string . IsNullOrWhiteSpace ( currentLine ) )
{
result . AppendLine ( ) ;
continue ;
}
// Basic heading detection (ALL CAPS lines)
if ( currentLine = = currentLine . ToUpper ( ) & & currentLine . Length > 20 )
{
result . AppendLine ( $"# {currentLine}" ) ;
}
// Basic list detection
else if ( currentLine . StartsWith ( "•" ) | | currentLine . StartsWith ( "*" ) )
{
result . AppendLine ( $"- {currentLine.Substring(1).Trim()}" ) ;
}
// Numbered list detection
else if ( System . Text . RegularExpressions . Regex . IsMatch ( currentLine , @"^\d+[\.\)]" ) )
{
result . AppendLine ( currentLine ) ;
}
// Normal text
else
{
result . AppendLine ( currentLine ) ;
}
}
return result . ToString ( ) . Trim ( ) ;
}
public void Dispose ( )
{
Dispose ( true ) ;
GC . SuppressFinalize ( this ) ;
}
protected virtual void Dispose ( bool disposing )
{
if ( ! _disposed )
{
if ( disposing )
{
_httpClient ? . Dispose ( ) ;
}
_disposed = true ;
}
}
~ OcrTextProcessor ( )
{
Dispose ( false ) ;
}
}
}