using System; using System.IO; using System.Windows; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Imaging; using System.Windows.Controls; using System.Windows.Shapes; using Tesseract; using System.Threading.Tasks; using Point = System.Windows.Point; using Rect = System.Windows.Rect; using Size = System.Windows.Size; using Brushes = System.Windows.Media.Brushes; using Cursors = System.Windows.Input.Cursors; using Cursor = System.Windows.Input.Cursor; using Color = System.Windows.Media.Color; using Path = System.IO.Path; using MessageBox = System.Windows.MessageBox; using MouseEventArgs = System.Windows.Input.MouseEventArgs; using KeyEventArgs = System.Windows.Input.KeyEventArgs; using Rectangle = System.Windows.Shapes.Rectangle; namespace GTPCorrgir { public class ScreenCaptureWindow : Window { private Point startPoint; private Point currentPoint; private bool hasFirstPoint; private System.Windows.Shapes.Rectangle selectionRectangle; private Canvas overlayCanvas; private readonly Cursor crosshairCursor = Cursors.Cross; private Window overlayWindow; private System.Windows.Forms.Screen targetScreen; // Añadimos esta referencia public ScreenCaptureWindow() { InitializeInitialWindow(); } private void InitializeInitialWindow() { // Calcular el rectángulo virtual que engloba todas las pantallas var allScreens = System.Windows.Forms.Screen.AllScreens; int minX = allScreens.Min(s => s.Bounds.Left); int minY = allScreens.Min(s => s.Bounds.Top); int maxX = allScreens.Max(s => s.Bounds.Right); int maxY = allScreens.Max(s => s.Bounds.Bottom); // Configurar la ventana inicial para cubrir todas las pantallas this.WindowStyle = WindowStyle.None; this.ResizeMode = ResizeMode.NoResize; this.Width = maxX - minX; this.Height = maxY - minY; this.Left = minX; this.Top = minY; this.AllowsTransparency = true; this.Background = new SolidColorBrush(Color.FromArgb(0, 0, 0, 0)); this.ShowInTaskbar = false; this.Topmost = true; this.Cursor = crosshairCursor; // Añadir un panel transparente que cubra toda la ventana var panel = new Grid { Background = new SolidColorBrush(Color.FromArgb(1, 0, 0, 0)) }; this.Content = panel; // Agregar el evento del primer clic this.MouseLeftButtonDown += InitialWindow_MouseLeftButtonDown; } private void InitialWindow_MouseLeftButtonDown(object sender, MouseButtonEventArgs e) { // Obtener la pantalla donde se hizo clic var clickPoint = PointToScreen(e.GetPosition(this)); Console.WriteLine($"Click point screen coords: X={clickPoint.X}, Y={clickPoint.Y}"); targetScreen = System.Windows.Forms.Screen.FromPoint( new System.Drawing.Point((int)clickPoint.X, (int)clickPoint.Y)); Console.WriteLine($"Target screen bounds: Left={targetScreen.Bounds.Left}, Top={targetScreen.Bounds.Top}, Right={targetScreen.Bounds.Right}, Bottom={targetScreen.Bounds.Bottom}"); // Remover este evento ya que solo lo necesitamos una vez this.MouseLeftButtonDown -= InitialWindow_MouseLeftButtonDown; // Calcular el punto relativo a la pantalla objetivo startPoint = new Point( clickPoint.X - targetScreen.Bounds.Left, clickPoint.Y - targetScreen.Bounds.Top ); Console.WriteLine($"Start point relative coords: X={startPoint.X}, Y={startPoint.Y}"); // Inicializar la ventana de overlay ANTES de posicionar el rectángulo InitializeOverlayWindow(targetScreen); // Asegurarse que el overlay esté completamente inicializado overlayWindow.Dispatcher.Invoke(() => { selectionRectangle.Visibility = Visibility.Visible; Canvas.SetLeft(selectionRectangle, startPoint.X); Canvas.SetTop(selectionRectangle, startPoint.Y); selectionRectangle.Width = 0; selectionRectangle.Height = 0; hasFirstPoint = true; }); } private void InitializeOverlayWindow(System.Windows.Forms.Screen screen) { overlayWindow = new Window { WindowStyle = WindowStyle.None, ResizeMode = ResizeMode.NoResize, AllowsTransparency = true, Background = new SolidColorBrush(Color.FromArgb(128, 0, 0, 0)), Topmost = true, ShowInTaskbar = false, Width = screen.Bounds.Width, Height = screen.Bounds.Height, WindowStartupLocation = WindowStartupLocation.Manual, Left = screen.Bounds.Left, Top = screen.Bounds.Top }; InitializeComponents(overlayWindow); SetupEventHandlers(); overlayWindow.Show(); overlayWindow.Activate(); // Asegurar que la ventana tiene el foco this.Hide(); } private void InitializeComponents(Window window) { overlayCanvas = new Canvas { HorizontalAlignment = System.Windows.HorizontalAlignment.Stretch, VerticalAlignment = System.Windows.VerticalAlignment.Stretch }; var grid = new Grid(); grid.Children.Add(overlayCanvas); window.Content = grid; selectionRectangle = new System.Windows.Shapes.Rectangle { Stroke = new SolidColorBrush(Colors.Red), StrokeThickness = 2, Fill = new SolidColorBrush(Color.FromArgb(50, 255, 255, 255)), Visibility = Visibility.Collapsed }; overlayCanvas.Children.Add(selectionRectangle); } private void SetupEventHandlers() { overlayWindow.MouseLeftButtonDown += OverlaySecondPoint_MouseLeftButtonDown; overlayWindow.MouseMove += OverlayCanvas_MouseMove; overlayWindow.KeyDown += MainWindow_KeyDown; } private void OverlayCanvas_MouseMove(object sender, MouseEventArgs e) { if (!hasFirstPoint) return; currentPoint = e.GetPosition(overlayCanvas); UpdateSelectionRectangle(startPoint, currentPoint); } private void OverlaySecondPoint_MouseLeftButtonDown(object sender, MouseButtonEventArgs e) { if (!hasFirstPoint) return; // Capturar el segundo punto var endPoint = e.GetPosition(overlayCanvas); // Validar el tamaño del rectángulo double width = Math.Abs(endPoint.X - startPoint.X); double height = Math.Abs(endPoint.Y - startPoint.Y); // Validar tamaño mínimo (5x5 pixels) const double MIN_SIZE = 5.0; if (width < MIN_SIZE || height < MIN_SIZE) { selectionRectangle.Visibility = Visibility.Collapsed; var notification = new notificacion(); notification.UpdateNotification("Selección muy pequeña", "Por favor, seleccione un área más grande (mínimo 5x5 píxeles)"); notification.Show(); hasFirstPoint = false; return; } // Ocultar el rectángulo inmediatamente selectionRectangle.Visibility = Visibility.Collapsed; // Mostrar notificación de procesamiento var processingNotification = new notificacion(); processingNotification.UpdateNotification("Procesando", "Analizando imagen seleccionada..."); processingNotification.Show(); // Si las validaciones pasan, proceder con la captura CaptureAndProcessArea(); } private void UpdateSelectionRectangle(Point start, Point current) { double x = Math.Min(start.X, current.X); double y = Math.Min(start.Y, current.Y); double width = Math.Abs(current.X - start.X); double height = Math.Abs(current.Y - start.Y); Canvas.SetLeft(selectionRectangle, x); Canvas.SetTop(selectionRectangle, y); selectionRectangle.Width = width; selectionRectangle.Height = height; } private void MainWindow_KeyDown(object sender, KeyEventArgs e) { if (e.Key == Key.Escape) { overlayWindow?.Close(); this.Close(); } } private string GetTesseractExecutablePath() { string baseDir = AppDomain.CurrentDomain.BaseDirectory; string tessDataDir = Path.Combine(baseDir, "tessdata"); if (!Directory.Exists(tessDataDir)) { throw new DirectoryNotFoundException( $"No se encontró el directorio tessdata en {tessDataDir}. " + "Asegúrate de que la carpeta tessdata existe y contiene los archivos de entrenamiento."); } return tessDataDir; } private BitmapSource CaptureScreen(double x, double y, double width, double height) { try { // Usar la referencia guardada del screen objetivo var screenPoint = new System.Drawing.Point( (int)(targetScreen.Bounds.Left + x), (int)(targetScreen.Bounds.Top + y) ); Console.WriteLine($"Capture coordinates: X={screenPoint.X}, Y={screenPoint.Y}, Width={width}, Height={height}"); using (var screenBmp = new System.Drawing.Bitmap( (int)width, (int)height, System.Drawing.Imaging.PixelFormat.Format32bppArgb)) { using (var bmpGraphics = System.Drawing.Graphics.FromImage(screenBmp)) { bmpGraphics.CopyFromScreen( screenPoint.X, screenPoint.Y, 0, 0, new System.Drawing.Size((int)width, (int)height) ); } using (var memory = new MemoryStream()) { screenBmp.Save(memory, System.Drawing.Imaging.ImageFormat.Png); memory.Position = 0; var bitmapImage = new BitmapImage(); bitmapImage.BeginInit(); bitmapImage.StreamSource = memory; bitmapImage.CacheOption = BitmapCacheOption.OnLoad; bitmapImage.EndInit(); bitmapImage.Freeze(); return bitmapImage; } } } catch (Exception ex) { MessageBox.Show($"Error al capturar pantalla: {ex.Message}"); return null; } } private async void CaptureAndProcessArea() { try { this.Hide(); await Task.Delay(100); double x = Canvas.GetLeft(selectionRectangle); double y = Canvas.GetTop(selectionRectangle); double width = selectionRectangle.Width; double height = selectionRectangle.Height; var screenCapture = CaptureScreen(x, y, width, height); if (screenCapture == null) return; var screenBitmap = new RenderTargetBitmap( (int)width, (int)height, 96, 96, PixelFormats.Pbgra32); var visual = new DrawingVisual(); using (var context = visual.RenderOpen()) { context.DrawImage(screenCapture, new Rect(0, 0, width, height)); } screenBitmap.Render(visual); var encoder = new PngBitmapEncoder(); encoder.Frames.Add(BitmapFrame.Create(screenBitmap)); using (var memoryStream = new MemoryStream()) { encoder.Save(memoryStream); memoryStream.Position = 0; string tesseractPath = GetTesseractExecutablePath(); using (var engine = new TesseractEngine(tesseractPath, "eng", EngineMode.Default)) { engine.SetVariable("tessedit_char_whitelist", " ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-."); using (var img = Pix.LoadFromMemory(memoryStream.ToArray())) { var result = engine.Process(img); string ocrText = result.GetText(); using (var textProcessor = new OcrTextProcessor()) { string processedText = await textProcessor.ProcessOcrText(ocrText); var notificationWindow = new notificacion(); notificationWindow.UpdateNotification("OCR Completado", "Texto copiado al portapapeles"); notificationWindow.Show(); } } } } } catch (Exception ex) { MessageBox.Show($"Error processing capture: {ex.Message}", "Error", MessageBoxButton.OK, MessageBoxImage.Error); } finally { overlayWindow?.Close(); this.Close(); } } } }