diff --git a/App.xaml.cs b/App.xaml.cs
index 30e78f8..baacb0a 100644
--- a/App.xaml.cs
+++ b/App.xaml.cs
@@ -80,6 +80,7 @@ namespace GTPCorrgir
case Opciones.modoDeUso.Corregir:
case Opciones.modoDeUso.Ortografia:
+ case Opciones.modoDeUso.PreguntaRespuesta:
case Opciones.modoDeUso.Traducir_a_Espanol:
case Opciones.modoDeUso.Traducir_a_Ingles:
case Opciones.modoDeUso.Traducir_a_Italiano:
@@ -154,8 +155,9 @@ namespace GTPCorrgir
$"Corrección en: {Math.Round(stopwatch.ElapsedMilliseconds / 1000.0, 1)} s");
if (Opciones.Instance.modo == Opciones.modoDeUso.Corregir || Opciones.Instance.modo == Opciones.modoDeUso.Ortografia ||
- Opciones.Instance.modo == Opciones.modoDeUso.Traducir_a_Espanol || Opciones.Instance.modo == Opciones.modoDeUso.Traducir_a_Ingles ||
- Opciones.Instance.modo == Opciones.modoDeUso.Traducir_a_Italiano || Opciones.Instance.modo == Opciones.modoDeUso.Traducir_a_Portugues)
+ Opciones.Instance.modo == Opciones.modoDeUso.PreguntaRespuesta || Opciones.Instance.modo == Opciones.modoDeUso.Traducir_a_Espanol ||
+ Opciones.Instance.modo == Opciones.modoDeUso.Traducir_a_Ingles || Opciones.Instance.modo == Opciones.modoDeUso.Traducir_a_Italiano ||
+ Opciones.Instance.modo == Opciones.modoDeUso.Traducir_a_Portugues)
{
if (Opciones.Instance.FuncionesOpcionales == Opciones.funcionesOpcionales.MostrarPopUp)
{
diff --git a/ContextMenuWindow.xaml.cs b/ContextMenuWindow.xaml.cs
index 4c62e16..4a9c176 100644
--- a/ContextMenuWindow.xaml.cs
+++ b/ContextMenuWindow.xaml.cs
@@ -124,14 +124,16 @@ namespace GTPCorrgir
private void CloseButton_Click(object sender, RoutedEventArgs e)
{
- this.Close();
+ // Cerrar toda la aplicación cuando se hace clic en el botón de cerrar
+ System.Windows.Application.Current.Shutdown();
}
private void Window_KeyDown(object sender, KeyEventArgs e)
{
if (e.Key == Key.Escape)
{
- this.Close();
+ // Cerrar toda la aplicación cuando se presiona Esc
+ System.Windows.Application.Current.Shutdown();
}
}
diff --git a/Documentation/PaddleOCRSharpAPI.txt b/Documentation/PaddleOCRSharpAPI.txt
new file mode 100644
index 0000000..17a020e
Binary files /dev/null and b/Documentation/PaddleOCRSharpAPI.txt differ
diff --git a/Documentation/paddleocr-api.md b/Documentation/paddleocr-api.md
new file mode 100644
index 0000000..b980c6a
--- /dev/null
+++ b/Documentation/paddleocr-api.md
@@ -0,0 +1,623 @@
+
+
+
+ PaddleOCRSharp
+
+
+
+
+ Base class for engine objects
+
+
+
+
+ Custom loading path for PaddleOCR.dll, default is empty. If specified, it needs to be assigned before engine instantiation.
+
+
+
+
+ Initialization
+
+
+
+
+ Get the current path of the program
+
+
+
+
+
+ Get the current path of the program
+
+
+
+
+
+ Convert Image to Byte[]
+
+
+
+
+
+
+ Release memory
+
+
+
+
+ Get underlying error information
+
+
+
+
+
+ Json helper class
+
+
+
+
+ Json deserialization
+
+
+
+
+
+
+
+ Model configuration object
+
+
+
+
+ det_infer model path
+
+
+
+
+ cls_infer model path
+
+
+
+
+ rec_infer model path
+
+
+
+
+ Full path of ppocr_keys.txt file
+
+
+
+
+ Table model configuration object
+
+
+
+
+ table_model_dir model path
+
+
+
+
+ Table recognition dictionary
+
+
+
+
+ OCR recognition parameters
+
+
+
+
+ Whether to use GPU; default false
+
+
+
+
+ GPU id, effective when using GPU; default 0
+
+
+
+
+ Requested GPU memory; default 4000
+
+
+
+
+ Number of threads for CPU prediction. When the machine has sufficient cores, the higher this value, the faster the prediction; default 10
+
+
+
+
+ Whether to use mkldnn library; default true
+
+
+
+
+ Whether to perform text detection; default true
+
+
+
+
+ Whether to perform text recognition; default true
+
+
+
+
+ Whether to perform text orientation classification; default false
+
+
+
+
+ When the input image length and width are greater than 960, the image is scaled proportionally so that the longest side is 960; default 960
+
+
+
+
+ Used to filter the binary image predicted by DB. Setting to 0.-0.3 has no significant effect on results; default 0.3
+
+
+
+
+ DB post-processing threshold for filtering boxes. If detection has missing boxes, this can be reduced accordingly; default 0.5
+
+
+
+
+ Represents the tightness of the text box. Smaller values mean the text box is closer to the text; default 1.6
+
+
+
+
+ Whether to use dilation on the output map, default false
+
+
+
+
+ true: use polygon box to calculate bbox; false: use rectangle box. Rectangle calculation is faster, polygon boxes are more accurate for curved text areas.
+
+
+
+
+ Whether to visualize the results. If true, the prediction results will be saved as an ocr_vis.png file in the current directory. Default false
+
+
+
+
+ Whether to use direction classifier, default false
+
+
+
+
+ Score threshold for direction classifier, default 0.9
+
+
+
+
+ Direction classifier batchsize, default 1
+
+
+
+
+ Recognition model batchsize, default 6
+
+
+
+
+ Recognition model input image height, default 48
+
+
+
+
+ Recognition model input image width, default 320
+
+
+
+
+ Whether to display prediction results, default false
+
+
+
+
+ When using GPU prediction, whether to enable tensorrt, default false
+
+
+
+
+ OCR modifiable parameters
+
+
+
+
+ Dynamically modify whether to detect. When OCRParameter.det=true, m_det can dynamically turn off the det parameter
+
+
+
+
+ Dynamically modify whether to recognize. When OCRParameter.rec=true, m_rec can dynamically turn off the rec parameter
+
+
+
+
+ When the input image length and width are greater than 960, the image is scaled proportionally so that the longest side is 960; default 960
+
+
+
+
+ Used to filter the binary image predicted by DB. Setting to 0.-0.3 has no significant effect on results; default 0.3. Effective when m_det=true
+
+
+
+
+ DB post-processing threshold for filtering boxes. If detection has missing boxes, this can be reduced accordingly; default 0.5. Effective when m_det=true
+
+
+
+
+ Represents the tightness of the text box. Smaller values mean the text box is closer to the text; default 1.6. Effective when m_det=true
+
+
+
+
+ OCR recognition result
+
+
+
+
+ List of text blocks
+
+
+
+
+ Recognition result text
+
+
+
+
+ Recognition result text in Json format
+
+
+
+
+ Return string format
+
+
+
+
+ Recognized text block
+
+
+
+
+ List of coordinate vertices around the text block
+
+
+
+
+ Text block content
+
+
+
+
+ Text recognition confidence
+
+
+
+
+ Angle classification confidence
+
+
+
+
+ Angle classification label
+
+
+
+
+ Return string format
+
+
+
+
+ Point object
+
+
+
+
+ X coordinate, in pixels
+
+
+
+
+ Y coordinate, in pixels
+
+
+
+
+ Default constructor
+
+
+
+
+ Constructor
+
+
+
+
+
+
+ Return string format
+
+
+
+
+ OCR structured recognition result
+
+
+
+
+ Table recognition result
+
+
+
+
+ Number of rows
+
+
+
+
+ Number of columns
+
+
+
+
+ List of cells
+
+
+
+
+ List of text blocks
+
+
+
+
+ Cell
+
+
+
+
+ Cell constructor
+
+
+
+
+ Row number
+
+
+
+
+ Column number
+
+
+
+
+ Text blocks
+
+
+
+
+ Recognized text
+
+
+
+
+ PaddleOCR text recognition engine object
+
+
+
+
+ Initialize OCR engine object with default parameters
+
+
+
+
+ Initialize OCR engine object with default parameters
+
+ Model configuration object, if null then default values are used
+
+
+
+ PaddleOCR recognition engine object initialization
+
+ Model configuration object, if null then default values are used
+ Recognition parameters, if null then default values are used
+
+
+
+ PaddleOCR recognition engine object initialization
+
+ Model configuration object, if null then default values are used
+ Recognition parameters in json string format
+
+
+
+ Get default configuration
+
+ Root directory
+
+
+
+ Perform text recognition on image file
+
+ Image file
+ OCR recognition result
+
+
+
+ Perform text recognition on image object
+
+ Image
+ OCR recognition result
+
+
+
+ Text recognition
+
+ Image memory stream
+ OCR recognition result
+
+
+
+ Text recognition
+
+ Image base64
+ OCR recognition result
+
+
+
+ Text recognition
+
+ Image memory address
+ Image width
+ Image height
+ Image channel, usually 3 or 1
+ OCR recognition result
+
+
+
+ Result parsing
+
+
+
+
+
+
+ Structured text recognition
+
+ Image
+ Table recognition result
+
+
+
+ Calculate table splitting
+
+
+
+
+
+
+
+ Dynamically modify parameters after initialization
+
+ Modifiable parameter object
+ Whether successful, calling before initialization will result in failure
+
+
+
+ Whether to enable rectangular processing of detection results. Single characters are easily detected as diamond shapes, processing them as rectangles can improve recognition accuracy. Only applicable for horizontal text.
+
+
+
+
+
+ Release object
+
+
+
+
+ PaddleOCR table recognition engine object
+
+
+
+
+ PaddleStructureEngine recognition engine object initialization
+
+
+
+
+ PaddleStructureEngine recognition engine object initialization
+
+ Model configuration object, if null then default values are used
+
+
+
+ PaddleStructureEngine recognition engine object initialization
+
+ Model configuration object, if null then default values are used
+ Recognition parameters, if null then default values are used
+
+
+
+ PaddleStructureEngine recognition engine object initialization
+
+ Model configuration object, if null then default values are used
+ Recognition parameters in Json format, if null then default values are used
+
+
+
+ Get default configuration
+
+ Root directory
+
+
+
+ Perform table text recognition on image file
+
+ Image file
+ Table recognition result
+
+
+
+ Perform table text recognition on image object
+
+ Image
+ Table recognition result
+
+
+
+ Perform table text recognition on image Byte array
+
+ Image byte array
+ Table recognition result
+
+
+
+ Perform table text recognition on image Base64
+
+ Image Base64
+ Table recognition result
+
+
+
+ Result parsing
+
+
+
+
+
+
+ Release object
+
+
+
+
+ OCR recognition parameters
+
+
+
+
+ When the input image length and width are greater than 488, the image is scaled proportionally, default 488
+
+
+
+
+ Whether to merge empty cells
+
+
+
+
+ Batch recognition quantity
+
+
+
+
diff --git a/GTPCorrgir.csproj b/GTPCorrgir.csproj
index 577eaab..20d59a6 100644
--- a/GTPCorrgir.csproj
+++ b/GTPCorrgir.csproj
@@ -20,10 +20,16 @@
+
+
+
+
+
+
diff --git a/Program.cs b/Program.cs
index 7ed0997..be054d1 100644
--- a/Program.cs
+++ b/Program.cs
@@ -30,6 +30,7 @@ namespace GTPCorrgir
Corregir,
Ortografia,
Chat,
+ PreguntaRespuesta,
Traducir_a_Ingles,
Traducir_a_Italiano,
Traducir_a_Espanol,
@@ -109,6 +110,8 @@ namespace GTPCorrgir
if (arg.Contains("Chat"))
Opciones.Instance.modo = Opciones.modoDeUso.Chat;
+ if (arg.Contains("PreguntaRespuesta"))
+ Opciones.Instance.modo = Opciones.modoDeUso.PreguntaRespuesta;
if (arg.Contains("Ortografia"))
Opciones.Instance.modo = Opciones.modoDeUso.Ortografia;
if (arg.Contains("Corregir"))
diff --git a/README.md b/README.md
index 1d646e7..1a35b35 100644
--- a/README.md
+++ b/README.md
@@ -15,6 +15,7 @@ Los parametros son:
* `--Chat` : Para crear una mini ventana que permite hacer chat con los modelos sellecionados.
* `--Corregir` (default) : Corrección desde el portapapeles y hacia el portapapeles
* `--Ortografia` : Revisar ortografía del texto en el portapapeles
+* `--PreguntaRespuesta` : Usar el texto del portapapeles como pregunta directa al LLM y devolver pregunta + respuesta
* `--Traducir_a_Ingles` : Traducir texto al inglés
* `--Traducir_a_Italiano` : Traducir texto al italiano
* `--Traducir_a_Espanol` : Traducir texto al español
diff --git a/Services/PaddleOCRManager.cs b/Services/PaddleOCRManager.cs
new file mode 100644
index 0000000..5db8d8c
--- /dev/null
+++ b/Services/PaddleOCRManager.cs
@@ -0,0 +1,88 @@
+using System;
+using System.IO;
+using System.Drawing;
+using System.Windows.Media;
+using System.Windows.Media.Imaging;
+using System.Windows;
+using System.Linq;
+using PaddleOCRSharp;
+
+namespace CtrEditor.Services
+{
+ // Clase auxiliar para gestionar PaddleOCR
+ public static class PaddleOCRManager
+ {
+ private static PaddleOCREngine _engine;
+ private static bool _initialized = false;
+ private static readonly object _lockObj = new object();
+
+ public static PaddleOCREngine GetEngine()
+ {
+ if (!_initialized)
+ {
+ lock (_lockObj)
+ {
+ if (!_initialized)
+ {
+ InitializeEngine();
+ _initialized = true;
+ }
+ }
+ }
+ return _engine;
+ }
+
+ private static void InitializeEngine()
+ {
+ try
+ {
+ string baseDir = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "paddleocr");
+
+ OCRModelConfig config = new OCRModelConfig
+ {
+ // Rutas a modelos de inferencia
+ det_infer = Path.Combine(baseDir, "det", "inference"),
+ cls_infer = Path.Combine(baseDir, "cls", "inference"),
+ rec_infer = Path.Combine(baseDir, "rec", "inference"),
+ keys = Path.Combine(baseDir, "keys", "ppocr_keys.txt")
+ };
+
+ OCRParameter parameter = new OCRParameter
+ {
+ // Configurar parámetros de OCR
+ use_angle_cls = true,
+ cls_thresh = 0.9f,
+ det_db_thresh = 0.3f,
+ det_db_box_thresh = 0.6f,
+ rec_batch_num = 6,
+ rec_img_h = 48,
+ enable_mkldnn = true,
+ use_gpu = false,
+ cpu_math_library_num_threads = Environment.ProcessorCount
+ };
+
+ _engine = new PaddleOCREngine(config, parameter);
+ }
+ catch (Exception ex)
+ {
+ System.Diagnostics.Debug.WriteLine($"Error al inicializar PaddleOCR: {ex.Message}");
+ // Fallback - inicializar con configuración predeterminada
+ _engine = new PaddleOCREngine();
+ }
+ }
+
+ public static void Cleanup()
+ {
+ lock (_lockObj)
+ {
+ if (_initialized && _engine != null)
+ {
+ _engine.Dispose();
+ _engine = null;
+ _initialized = false;
+ }
+ }
+ }
+ }
+
+}
\ No newline at end of file
diff --git a/gtpask.cs b/gtpask.cs
index 042b38d..496e838 100644
--- a/gtpask.cs
+++ b/gtpask.cs
@@ -258,15 +258,25 @@ namespace GTPCorrgir
private void ProcesarRespuestaLLM(string respuestaLLM)
{
- TextoCorregido = ExtraerValorUnicoJSON(respuestaLLM);
- if (TextoCorregido == null)
+ string respuestaExtraida = ExtraerValorUnicoJSON(respuestaLLM);
+ if (respuestaExtraida == null)
{
throw new ApplicationException("Error al extraer el texto corregido de la respuesta JSON");
}
- TextoCorregido = System.Text.RegularExpressions.Regex.Replace(TextoCorregido, @"\*\*(.*?)\*\*", "$1");
- TextoCorregido = _markdownProcessor.RemoveTechnicalTermMarkers_IgnoreCase(TextoCorregido).Trim('"');
- TextoCorregido = _markdownProcessor.RemoveDoubleBrackets(TextoCorregido);
+ respuestaExtraida = System.Text.RegularExpressions.Regex.Replace(respuestaExtraida, @"\*\*(.*?)\*\*", "$1");
+ respuestaExtraida = _markdownProcessor.RemoveTechnicalTermMarkers_IgnoreCase(respuestaExtraida).Trim('"');
+ respuestaExtraida = _markdownProcessor.RemoveDoubleBrackets(respuestaExtraida);
+
+ // Para el modo Pregunta-Respuesta, combinar pregunta original con la respuesta
+ if (Opciones.Instance.modo == Opciones.modoDeUso.PreguntaRespuesta)
+ {
+ TextoCorregido = $"{TextoACorregir}\n{respuestaExtraida}";
+ }
+ else
+ {
+ TextoCorregido = respuestaExtraida;
+ }
}
private async Task SimularCorreccion()
@@ -312,6 +322,9 @@ namespace GTPCorrgir
Opciones.modoDeUso.Ortografia =>
"Please check the following text for spelling errors and provide the corrected version. Do not change the meaning or structure of the sentences. If you find words enclosed in double brackets [[like this]], preserve them exactly as they appear. For all other words, only correct spelling mistakes while preserving technical terms. Preserve any existing markdown language if present, but do not introduce new markdown styling (such as bold or italics) for emphasis unless it was part of the original input. Please write in " + IdiomaDetectado + " and respond in the following JSON format: { \"Rewritten_text\": \"Your text here\" }.",
+ Opciones.modoDeUso.PreguntaRespuesta =>
+ "You are a helpful assistant specialized in industrial automation and technical topics. Please answer the user's question accurately and clearly. If the question contains words in double brackets [[like this]], preserve them exactly as they appear in your response. Please write your answer in " + IdiomaDetectado + " and respond in the following JSON format: { \"Reply_text\": \"Your answer here\" }.",
+
_ => "You are an engineer working specialized in industrial automation. If the question contains words in double brackets [[like this]], preserve them exactly as they appear. Please answer the following question in " + IdiomaDetectado + " and respond in the following JSON format: { \"Reply_text\": \"Your text here\" }."
};
}
@@ -325,6 +338,9 @@ namespace GTPCorrgir
Opciones.modoDeUso.Ortografia =>
$"Please check the following text for spelling errors and provide the corrected version. Do not change the meaning or structure of the sentences. Only correct any spelling mistakes you find on: \"{texto}\"",
+ Opciones.modoDeUso.PreguntaRespuesta =>
+ texto, // Para pregunta-respuesta, enviamos el texto directamente como la pregunta
+
Opciones.modoDeUso.Traducir_a_Ingles =>
$"Please check the following text for spelling errors and provide the corrected version tranlated to English. Do not change the meaning or structure of the sentences. Only correct any spelling mistakes you find on: \"{texto}\"",
diff --git a/paddleocr/cls/inference/._inference.pdiparams b/paddleocr/cls/inference/._inference.pdiparams
new file mode 100644
index 0000000..30c9fb5
Binary files /dev/null and b/paddleocr/cls/inference/._inference.pdiparams differ
diff --git a/paddleocr/cls/inference/._inference.pdiparams.info b/paddleocr/cls/inference/._inference.pdiparams.info
new file mode 100644
index 0000000..30c9fb5
Binary files /dev/null and b/paddleocr/cls/inference/._inference.pdiparams.info differ
diff --git a/paddleocr/cls/inference/._inference.pdmodel b/paddleocr/cls/inference/._inference.pdmodel
new file mode 100644
index 0000000..30c9fb5
Binary files /dev/null and b/paddleocr/cls/inference/._inference.pdmodel differ
diff --git a/paddleocr/cls/inference/inference.pdiparams b/paddleocr/cls/inference/inference.pdiparams
new file mode 100644
index 0000000..e3b3215
Binary files /dev/null and b/paddleocr/cls/inference/inference.pdiparams differ
diff --git a/paddleocr/cls/inference/inference.pdiparams.info b/paddleocr/cls/inference/inference.pdiparams.info
new file mode 100644
index 0000000..341c265
Binary files /dev/null and b/paddleocr/cls/inference/inference.pdiparams.info differ
diff --git a/paddleocr/cls/inference/inference.pdmodel b/paddleocr/cls/inference/inference.pdmodel
new file mode 100644
index 0000000..7e0540f
Binary files /dev/null and b/paddleocr/cls/inference/inference.pdmodel differ
diff --git a/paddleocr/det/inference/.DS_Store b/paddleocr/det/inference/.DS_Store
new file mode 100644
index 0000000..5b91d33
Binary files /dev/null and b/paddleocr/det/inference/.DS_Store differ
diff --git a/paddleocr/det/inference/._.DS_Store b/paddleocr/det/inference/._.DS_Store
new file mode 100644
index 0000000..f8ab1f9
Binary files /dev/null and b/paddleocr/det/inference/._.DS_Store differ
diff --git a/paddleocr/det/inference/._inference.pdiparams b/paddleocr/det/inference/._inference.pdiparams
new file mode 100644
index 0000000..b86c9ea
Binary files /dev/null and b/paddleocr/det/inference/._inference.pdiparams differ
diff --git a/paddleocr/det/inference/._inference.pdiparams.info b/paddleocr/det/inference/._inference.pdiparams.info
new file mode 100644
index 0000000..b86c9ea
Binary files /dev/null and b/paddleocr/det/inference/._inference.pdiparams.info differ
diff --git a/paddleocr/det/inference/._inference.pdmodel b/paddleocr/det/inference/._inference.pdmodel
new file mode 100644
index 0000000..b86c9ea
Binary files /dev/null and b/paddleocr/det/inference/._inference.pdmodel differ
diff --git a/paddleocr/det/inference/inference.pdiparams b/paddleocr/det/inference/inference.pdiparams
new file mode 100644
index 0000000..a21c592
Binary files /dev/null and b/paddleocr/det/inference/inference.pdiparams differ
diff --git a/paddleocr/det/inference/inference.pdiparams.info b/paddleocr/det/inference/inference.pdiparams.info
new file mode 100644
index 0000000..00e756f
Binary files /dev/null and b/paddleocr/det/inference/inference.pdiparams.info differ
diff --git a/paddleocr/det/inference/inference.pdmodel b/paddleocr/det/inference/inference.pdmodel
new file mode 100644
index 0000000..1c8e6ce
Binary files /dev/null and b/paddleocr/det/inference/inference.pdmodel differ
diff --git a/paddleocr/download-paddleocr-models.ps1 b/paddleocr/download-paddleocr-models.ps1
new file mode 100644
index 0000000..f31d53e
--- /dev/null
+++ b/paddleocr/download-paddleocr-models.ps1
@@ -0,0 +1,132 @@
+# Script para descargar e instalar modelos PaddleOCR
+# Guardar como: download-paddleocr-models.ps1
+
+param(
+ [string]$OutputDirectory = ".\paddleocr",
+ [switch]$ForceDownload = $false
+)
+
+# URLs de modelos PaddleOCR (inglés por defecto)
+$modelUrls = @{
+ "det" = "https://paddleocr.bj.bcebos.com/PP-OCRv3/english/en_PP-OCRv3_det_slim_infer.tar"
+ "rec" = "https://paddleocr.bj.bcebos.com/PP-OCRv3/english/en_PP-OCRv3_rec_slim_infer.tar"
+ "cls" = "https://paddleocr.bj.bcebos.com/dygraph_v2.0/ch/ch_ppocr_mobile_v2.0_cls_slim_infer.tar"
+ "keys" = "https://raw.githubusercontent.com/PaddlePaddle/PaddleOCR/release/2.6/ppocr/utils/en_dict.txt"
+}
+
+# Crear directorios si no existen
+function EnsureDirectory($path) {
+ if (-not (Test-Path $path)) {
+ New-Item -Path $path -ItemType Directory | Out-Null
+ Write-Host "Creado directorio: $path" -ForegroundColor Green
+ }
+}
+
+# Descargar archivo con barra de progreso
+function DownloadFile($url, $outputFile) {
+ $webClient = New-Object System.Net.WebClient
+ $webClient.Encoding = [System.Text.Encoding]::UTF8
+
+ $downloadExists = Test-Path $outputFile
+ if ($downloadExists -and -not $ForceDownload) {
+ Write-Host "El archivo ya existe: $outputFile. Use -ForceDownload para sobrescribir." -ForegroundColor Yellow
+ return $false
+ }
+
+ Write-Host "Descargando $url..." -ForegroundColor Cyan
+ try {
+ $webClient.DownloadFile($url, $outputFile)
+ Write-Host "Descarga completada: $outputFile" -ForegroundColor Green
+ return $true
+ } catch {
+ Write-Host "Error al descargar $url : $_" -ForegroundColor Red
+ return $false
+ }
+}
+
+# Extraer archivo TAR
+function ExtractTarFile($tarFile, $destDir) {
+ Write-Host "Extrayendo $tarFile..." -ForegroundColor Cyan
+
+ # Verificar si tar está disponible
+ $tarAvailable = $null -ne (Get-Command "tar" -ErrorAction SilentlyContinue)
+
+ if ($tarAvailable) {
+ # Usar tar nativo
+ try {
+ tar -xf $tarFile -C $destDir
+ Write-Host "Extracción completada: $tarFile" -ForegroundColor Green
+ return $true
+ } catch {
+ Write-Host "Error al extraer con tar: $_" -ForegroundColor Red
+ }
+ }
+
+ # Fallback a .NET
+ try {
+ Add-Type -AssemblyName System.IO.Compression.FileSystem
+
+ # Descomprimir TAR con .NET
+ # Nota: Esto es un ejemplo simplificado. Necesitarías una biblioteca específica para TAR
+ Write-Host "TAR nativo no disponible. Se requiere una biblioteca para manejar archivos TAR." -ForegroundColor Yellow
+
+ # Aquí puedes agregar código para usar SharpCompress u otra biblioteca para TAR
+ # Por ejemplo:
+ # [Reflection.Assembly]::LoadFrom("path\to\SharpCompress.dll")
+ # $reader = [SharpCompress.Readers.ReaderFactory]::Open($tarFile)
+ # ...
+
+ return $false
+ } catch {
+ Write-Host "Error al extraer $tarFile : $_" -ForegroundColor Red
+ return $false
+ }
+}
+
+# Crear directorio principal
+EnsureDirectory $OutputDirectory
+
+# Crear estructura de directorios
+$modelTypes = @("det", "rec", "cls", "keys")
+foreach ($type in $modelTypes) {
+ $typeDir = Join-Path $OutputDirectory $type
+ EnsureDirectory $typeDir
+
+ if ($type -ne "keys") {
+ $inferenceDir = Join-Path $typeDir "inference"
+ EnsureDirectory $inferenceDir
+ }
+}
+
+# Descargar y procesar cada modelo
+foreach ($entry in $modelUrls.GetEnumerator()) {
+ $type = $entry.Key
+ $url = $entry.Value
+ $typeDir = Join-Path $OutputDirectory $type
+
+ if ($type -eq "keys") {
+ # Para el archivo de claves, solo descargarlo directamente
+ $outputFile = Join-Path $typeDir "ppocr_keys.txt"
+ DownloadFile $url $outputFile
+ } else {
+ # Para los modelos, descargar TAR y extraerlo
+ $tarFile = Join-Path $env:TEMP "$type.tar"
+
+ $downloaded = DownloadFile $url $tarFile
+ if ($downloaded) {
+ $extracted = ExtractTarFile $tarFile $typeDir
+
+ # Limpiar archivo temporal
+ if (Test-Path $tarFile) {
+ Remove-Item $tarFile -Force
+ }
+ }
+ }
+}
+
+Write-Host "`nInstalación de modelos PaddleOCR completada en: $OutputDirectory" -ForegroundColor Green
+Write-Host "Para usar estos modelos, configura PaddleOCREngine con las siguientes rutas:" -ForegroundColor Yellow
+Write-Host " - det_infer: $OutputDirectory\det\inference" -ForegroundColor White
+Write-Host " - rec_infer: $OutputDirectory\rec\inference" -ForegroundColor White
+Write-Host " - cls_infer: $OutputDirectory\cls\inference" -ForegroundColor White
+Write-Host " - keys: $OutputDirectory\keys\ppocr_keys.txt" -ForegroundColor White
diff --git a/paddleocr/keys/ppocr_keys.txt b/paddleocr/keys/ppocr_keys.txt
new file mode 100644
index 0000000..7677d31
--- /dev/null
+++ b/paddleocr/keys/ppocr_keys.txt
@@ -0,0 +1,95 @@
+0
+1
+2
+3
+4
+5
+6
+7
+8
+9
+:
+;
+<
+=
+>
+?
+@
+A
+B
+C
+D
+E
+F
+G
+H
+I
+J
+K
+L
+M
+N
+O
+P
+Q
+R
+S
+T
+U
+V
+W
+X
+Y
+Z
+[
+\
+]
+^
+_
+`
+a
+b
+c
+d
+e
+f
+g
+h
+i
+j
+k
+l
+m
+n
+o
+p
+q
+r
+s
+t
+u
+v
+w
+x
+y
+z
+{
+|
+}
+~
+!
+"
+#
+$
+%
+&
+'
+(
+)
+*
++
+,
+-
+.
+/
+
diff --git a/paddleocr/rec/inference/inference.pdiparams b/paddleocr/rec/inference/inference.pdiparams
new file mode 100644
index 0000000..baa7670
Binary files /dev/null and b/paddleocr/rec/inference/inference.pdiparams differ
diff --git a/paddleocr/rec/inference/inference.pdiparams.info b/paddleocr/rec/inference/inference.pdiparams.info
new file mode 100644
index 0000000..357f09b
Binary files /dev/null and b/paddleocr/rec/inference/inference.pdiparams.info differ
diff --git a/paddleocr/rec/inference/inference.pdmodel b/paddleocr/rec/inference/inference.pdmodel
new file mode 100644
index 0000000..8d5230a
Binary files /dev/null and b/paddleocr/rec/inference/inference.pdmodel differ