Escenarios de Aplicación
- Gestión de productos de comercio electrónico: Procesamiento por lotes de imágenes de productos, reconocimiento de información como nombre del producto, modelo y precio desde regiones fijas, renombrado en formato "nombre_producto_modelo_precio.jpg"
- Digitalización de archivos: Imágenes de documentos escaneados como contratos, reconocimiento de información clave como número de contrato y fecha desde posiciones fijas para renombrar
- Gestión de documentos logísticos: Reconocimiento de información como número de vehículo y número de lote en albaranes para renombrar imágenes y facilitar la búsqueda rápida
- Procesamiento de facturas: Reconocimiento de información como número de factura y monto desde regiones fijas para nombrar archivos
Diseño de Itnerfaz
Reconocimiento de regiones y renombrado por lotes de PDF e imágenes:
<Window x:Class="RenombradorOCRAlibabaCloud.VentanaPrincipal"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Herramienta de Reconocimiento y Renombrado de Imágenes" Height="550" Width="800">
<Grid>
<!-- Área de selección de archivos -->
<Button Content="Seleccionar carpeta de imágenes" HorizontalAlignment="Left" Margin="20,20,0,0" VerticalAlignment="Top" Width="150" Click="SeleccionarCarpetaImagenes_Click"/>
<TextBox x:Name="CarpetaImagenesTextBox" HorizontalAlignment="Left" Height="23" Margin="180,20,0,0" TextWrapping="Wrap" VerticalAlignment="Top" Width="580" IsReadOnly="True"/>
<!-- Configuración de Alibaba Cloud -->
<Label Content="AccessKey ID de Alibaba Cloud:" HorizontalAlignment="Left" Margin="20,60,0,0" VerticalAlignment="Top"/>
<TextBox x:Name="ClaveAccesoTextBox" HorizontalAlignment="Left" Height="23" Margin="150,60,0,0" VerticalAlignment="Top" Width="200"/>
<Label Content="AccessKey Secret de Alibaba Cloud:" HorizontalAlignment="Left" Margin="20,90,0,0" VerticalAlignment="Top"/>
<PasswordBox x:Name="ClaveSecretaBox" HorizontalAlignment="Left" Height="23" Margin="150,90,0,0" VerticalAlignment="Top" Width="200"/>
<!-- Configuración de región -->
<Label Content="Configuración de región de reconocimiento (formato: izquierda,arriba,ancho,alto)" HorizontalAlignment="Left" Margin="20,130,0,0" VerticalAlignment="Top"/>
<TextBox x:Name="RegionTextBox" HorizontalAlignment="Left" Height="23" Margin="20,160,0,0" VerticalAlignment="Top" Width="740" Text="100,100,200,50"/>
<!-- Área de vista previa -->
<Image x:Name="ImagenVistaPrevia" HorizontalAlignment="Left" Margin="20,200,0,0" VerticalAlignment="Top" Width="300" Height="200"/>
<Button Content="Seleccionar imagen de vista previa" HorizontalAlignment="Left" Margin="20,410,0,0" VerticalAlignment="Top" Width="100" Click="SeleccionarImagenVistaPrevia_Click"/>
<!-- Control de procesamiento -->
<Button Content="Iniciar procesamiento" HorizontalAlignment="Left" Margin="350,450,0,0" VerticalAlignment="Top" Width="100" Click="IniciarProcesamiento_Click"/>
<!-- Registro de salida -->
<TextBox x:Name="RegistroTextBox" HorizontalAlignment="Left" Height="100" Margin="400,200,0,0" VerticalAlignment="Top" Width="360" IsReadOnly="True" VerticalScrollBarVisibility="Auto"/>
</Grid>
</Window>
Implementación Detallada
- Preparación del Entorno
- Instalar Visual Studio y crear un proyecto WPF
- Instalar el SDK de Alibaba Cloud a través de NuGet:
Install-Package Aliyun.SDK.OCR-20191230 - Activar el servicio OCR en la consola de Alibaba Cloud y obtener AccessKey ID y Secret
- Implementación del Código Central
using Aliyun.Acs.Core;
using Aliyun.Acs.Core.Profile;
using Aliyun.Acs.OCR.Model.V20191230;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Windows;
using System.Windows.Media.Imaging;
namespace RenombradorOCRAlibabaCloud
{
public partial class VentanaPrincipal : Window
{
private string rutaCarpetaImagenes;
public VentanaPrincipal()
{
InitializeComponent();
}
private void SeleccionarCarpetaImagenes_Click(object sender, RoutedEventArgs e)
{
var dialogo = new System.Windows.Forms.FolderBrowserDialog();
if (dialogo.ShowDialog() == System.Windows.Forms.DialogResult.OK)
{
rutaCarpetaImagenes = dialogo.SelectedPath;
CarpetaImagenesTextBox.Text = rutaCarpetaImagenes;
}
}
private void SeleccionarImagenVistaPrevia_Click(object sender, RoutedEventArgs e)
{
var dialogo = new Microsoft.Win32.OpenFileDialog();
dialogo.Filter = "Archivos de imagen (*.jpg, *.jpeg, *.png)|*.jpg;*.jpeg;*.png";
if (dialogo.ShowDialog() == true)
{
ImagenVistaPrevia.Source = new BitmapImage(new Uri(dialogo.FileName));
}
}
private void IniciarProcesamiento_Click(object sender, RoutedEventArgs e)
{
if (string.IsNullOrEmpty(rutaCarpetaImagenes))
{
MessageBox.Show("Por favor, seleccione primero una carpeta de imágenes");
return;
}
// Obtener configuración de Alibaba Cloud
string idClaveAcceso = ClaveAccesoTextBox.Text;
string claveSecreta = ClaveSecretaBox.Password;
if (string.IsNullOrEmpty(idClaveAcceso) || string.IsNullOrEmpty(claveSecreta))
{
MessageBox.Show("Por favor, ingrese el AccessKey ID y Secret de Alibaba Cloud");
return;
}
// Analizar región de reconocimiento
var partesRegion = RegionTextBox.Text.Split(',');
if (partesRegion.Length != 4)
{
MessageBox.Show("El formato de la región de reconocimiento es incorrecto, debe ser izquierda,arriba,ancho,alto");
return;
}
int izquierda = int.Parse(partesRegion[0]);
int arriba = int.Parse(partesRegion[1]);
int ancho = int.Parse(partesRegion[2]);
int alto = int.Parse(partesRegion[3]);
// Obtener todos los archivos de imagen
var archivosImagen = Directory.GetFiles(rutaCarpetaImagenes, "*.*", SearchOption.AllDirectories)
.Where(archivo => archivo.ToLower().EndsWith(".jpg") ||
archivo.ToLower().EndsWith(".jpeg") ||
archivo.ToLower().EndsWith(".png")).ToList();
// Inicializar cliente de Alibaba Cloud
IClientProfile perfil = DefaultProfile.GetProfile("cn-hangzhou", idClaveAcceso, claveSecreta);
DefaultAcsClient cliente = new DefaultAcsClient(perfil);
// Procesar cada imagen
foreach (var archivoImagen in archivosImagen)
{
try
{
// Leer imagen y convertir a Base64
byte[] bytesImagen = File.ReadAllBytes(archivoImagen);
string imagenBase64 = Convert.ToBase64String(bytesImagen);
// Crear solicitud OCR
var solicitud = new RecognizeCharacterRequest();
solicitud.ImageURL = "";
solicitud.ImageData = imagenBase64;
solicitud.MinHeight = 10;
solicitud.OutputProbability = false;
// Establecer región de reconocimiento
solicitud.Task = new List<RecognizeCharacterRequest.TaskItem>
{
new RecognizeCharacterRequest.TaskItem
{
ImageData = imagenBase64,
RegionType = 1,
RegionInfo = new RecognizeCharacterRequest.TaskItemRegionInfo
{
Left = izquierda,
Top = arriba,
Width = ancho,
Height = alto
}
}
};
// Enviar solicitud OCR
var respuesta = cliente.GetAcsResponse(solicitud);
if (respuesta.Data != null && respuesta.Data.Outputs != null && respuesta.Data.Outputs.Count > 0)
{
// Obtener resultado del reconocimiento
string textoReconocido = respuesta.Data.Outputs[0].OutputValue.DataValue;
// Limpiar caracteres no válidos del nombre de archivo
string nombreArchivoSeguro = string.Join("_", textoReconocido.Split(Path.GetInvalidFileNameChars()));
// Construir nuevo nombre de archivo
string nuevoNombreArchivo = $"{nombreArchivoSeguro}{Path.GetExtension(archivoImagen)}";
string nuevaRutaArchivo = Path.Combine(Path.GetDirectoryName(archivoImagen), nuevoNombreArchivo);
// Manejar conflictos de nombres de archivo
if (File.Exists(nuevaRutaArchivo))
{
nuevoNombreArchivo = $"{nombreArchivoSeguro}_{Guid.NewGuid().ToString().Substring(0, 4)}{Path.GetExtension(archivoImagen)}";
nuevaRutaArchivo = Path.Combine(Path.GetDirectoryName(archivoImagen), nuevoNombreArchivo);
}
// Renombrar archivo
File.Move(archivoImagen, nuevaRutaArchivo);
// Registrar en el log
RegistroTextBox.AppendText($"Renombrado exitoso: {Path.GetFileName(archivoImagen)} -> {nuevoNombreArchivo}\n");
}
}
catch (Exception ex)
{
RegistroTextBox.AppendText($"Error al procesar el archivo {Path.GetFileName(archivoImagen)}: {ex.Message}\n");
}
}
RegistroTextBox.AppendText("¡Procesamiento completado!\n");
}
}
}
Optimización y Consideraciones
- Optimización del rendimiento:
- Utilizar procesamiento multihilo o asíncrono para aumentar la velocidad de procesamiento por lotes
- Realizar llamadas masivas a la API OCR de Alibaba Cloud para reducir el número de solicitudes de red
- Mejora de la precisión:
- Agregar funciones de preprocesamiento de imágenes (como escala de grises, binarización, nitidez) para mejorar la tasa de reconocimiento OCR
- Implementar reconocimianto de múltiples regiones, combinando resultados de varias áreas para generar nombres de archivo
- Mejoras en la experiencia del usuario:
- Agregar función de selección de región visual, permitiendo a los usuarios seleccionar directamente el área de reconocimiento en la imagen
- Implementar vista previa de resultados de reconocimiento y función de corrección manual
- Agregar barra de progreso para mostrar el estado del procesamiento
- Expansión de funcionalidades:
- Soportar reconocimiento y renombrado de regiones en archivos PDF
- Agregar función de plantillas de reglas para guardar configuraciones de regiones de reconocimiento comunes
- Permitir exportar resultados de reconocimiento a tablas Excel
Consideraciones Importantes
- El servicio OCR de Alibaba Cloud tiene límites de frecuencia de llamada, es necesario manejar problemas de limitación al procesar grandes cantidades de archivos
- La longitud del nombre de archivo está limitada a 255 caracteres, es necesario truncar los resultados del reconocimiento
- La calidad de la imagen afecta directamente la precisión del reconocimiento, se recomienda verificar la claridad de las imágenes antes del procesamiento
- El servicio OCR de Alibaba Cloud genera costos, es necesario controlar los gastos
Esta solución combina las ventajas de la interfaz WPF con la potente capacidad de reconocimiento de Alibaba Cloud OCR, pudiendo resolver eficazmente las necesidades de reconocimiento de regiones y renombrado por lotes de imágenes, especialmente adecuada para tareas de procesamiento automatizado de archivos en escenarios como comercio electrónico y gestión de archivos.