GTPCorrgir/ScreenCaptureWindow.cs

348 lines
13 KiB
C#

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;
using System.Windows.Data;
using Binding = System.Windows.Data.Binding;
using Image = System.Windows.Controls.Image;
namespace GTPCorrgir
{
public class ScreenCaptureWindow : Window
{
private Point startPoint;
private Point currentPoint;
private bool hasFirstPoint;
private Rectangle selectionRectangle;
private Canvas overlayCanvas;
private readonly Cursor crosshairCursor = Cursors.Cross;
private bool isSelecting;
private TextBlock dimensionsText;
public ScreenCaptureWindow()
{
InitializeOverlayWindow();
}
private void InitializeOverlayWindow()
{
// Calcular el rectángulo virtual que engloba todas las pantallas
var virtualScreen = GetVirtualScreenBounds();
// Configurar la ventana principal
this.WindowStyle = WindowStyle.None;
this.ResizeMode = ResizeMode.NoResize;
this.AllowsTransparency = true;
this.Background = new SolidColorBrush(Color.FromArgb(128, 0, 0, 0));
this.ShowInTaskbar = false;
this.Topmost = true;
this.Cursor = crosshairCursor;
// Establecer la posición y tamaño para cubrir todas las pantallas
this.Left = virtualScreen.Left;
this.Top = virtualScreen.Top;
this.Width = virtualScreen.Width;
this.Height = virtualScreen.Height;
InitializeComponents();
SetupEventHandlers();
}
private System.Drawing.Rectangle GetVirtualScreenBounds()
{
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);
return new System.Drawing.Rectangle(minX, minY, maxX - minX, maxY - minY);
}
private void InitializeComponents()
{
overlayCanvas = new Canvas();
// Obtener el área virtual que engloba todas las pantallas
var virtualScreen = GetVirtualScreenBounds();
// Capturar toda el área de pantallas
var screenBitmap = CaptureScreen(virtualScreen.Left, virtualScreen.Top, virtualScreen.Width, virtualScreen.Height);
// Crear imagen con la captura
var screenImage = new Image
{
Source = screenBitmap,
Width = virtualScreen.Width,
Height = virtualScreen.Height,
Opacity = 0.3 // Esto oscurece toda la imagen
};
// Crear imagen para el área seleccionada (la misma captura pero opacidad normal)
var selectionImage = new Image
{
Source = screenBitmap,
Width = virtualScreen.Width,
Height = virtualScreen.Height,
Opacity = 1
};
// Crear el clip para la imagen de selección
var clipRectangle = new RectangleGeometry();
selectionImage.Clip = clipRectangle;
selectionImage.Visibility = Visibility.Collapsed;
// Rectángulo de selección (solo el borde)
selectionRectangle = new Rectangle
{
Stroke = new SolidColorBrush(Color.FromRgb(120, 255, 120)),
StrokeThickness = 1.5,
Fill = Brushes.Transparent,
Visibility = Visibility.Collapsed
};
// Agregar todos los elementos al canvas
overlayCanvas.Children.Add(screenImage);
overlayCanvas.Children.Add(selectionImage);
overlayCanvas.Children.Add(selectionRectangle);
// Actualizar el clip cuando se mueve el rectángulo
selectionRectangle.LayoutUpdated += (s, e) =>
{
if (selectionRectangle.Visibility == Visibility.Visible)
{
selectionImage.Visibility = Visibility.Visible;
clipRectangle.Rect = new Rect(
Canvas.GetLeft(selectionRectangle),
Canvas.GetTop(selectionRectangle),
selectionRectangle.Width,
selectionRectangle.Height
);
}
else
{
selectionImage.Visibility = Visibility.Collapsed;
}
};
this.Content = overlayCanvas;
}
private void UpdateSelectionRectangle(Point start, Point current)
{
double left = Math.Min(start.X, current.X);
double top = 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, left);
Canvas.SetTop(selectionRectangle, top);
selectionRectangle.Width = width;
selectionRectangle.Height = height;
}
private void SetupEventHandlers()
{
this.MouseLeftButtonDown += Overlay_MouseLeftButtonDown;
this.MouseLeftButtonUp += Overlay_MouseLeftButtonUp;
this.MouseMove += Overlay_MouseMove;
this.KeyDown += Window_KeyDown;
}
private void Overlay_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
if (!hasFirstPoint)
{
// Primer punto
startPoint = e.GetPosition(overlayCanvas);
hasFirstPoint = true;
isSelecting = true;
selectionRectangle.Visibility = Visibility.Visible;
UpdateSelectionRectangle(startPoint, startPoint);
}
}
private void Overlay_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
{
if (hasFirstPoint && isSelecting)
{
isSelecting = false;
currentPoint = e.GetPosition(overlayCanvas);
double width = Math.Abs(currentPoint.X - startPoint.X);
double height = Math.Abs(currentPoint.Y - startPoint.Y);
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;
}
selectionRectangle.Visibility = Visibility.Collapsed;
var processingNotification = new notificacion();
processingNotification.UpdateNotification("Procesando", "Analizando imagen seleccionada...");
processingNotification.Show();
CaptureAndProcessArea();
}
}
private void Overlay_MouseMove(object sender, MouseEventArgs e)
{
if (hasFirstPoint && isSelecting)
{
currentPoint = e.GetPosition(overlayCanvas);
UpdateSelectionRectangle(startPoint, currentPoint);
}
}
private BitmapSource CaptureScreen(double x, double y, double width, double height)
{
try
{
// Las coordenadas ya están en el espacio de la pantalla virtual
var screenPoint = new System.Drawing.Point((int)x, (int)y);
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}");
Console.WriteLine($"Stack trace: {ex.StackTrace}");
return null;
}
}
private async void CaptureAndProcessArea()
{
try
{
double x = Canvas.GetLeft(selectionRectangle);
double y = Canvas.GetTop(selectionRectangle);
double width = selectionRectangle.Width;
double height = selectionRectangle.Height;
// Ajustar las coordenadas al origen de la pantalla virtual
x += this.Left;
y += this.Top;
var screenCapture = CaptureScreen(x, y, width, height);
if (screenCapture == null) return;
// Resto del procesamiento OCR igual que antes
using (var memoryStream = new MemoryStream())
{
var encoder = new PngBitmapEncoder();
encoder.Frames.Add(BitmapFrame.Create(screenCapture));
encoder.Save(memoryStream);
memoryStream.Position = 0;
string tesseractPath = GetTesseractExecutablePath();
using (var engine = new TesseractEngine(tesseractPath, "eng", EngineMode.Default))
{
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
{
this.Close();
}
}
private void Window_KeyDown(object sender, KeyEventArgs e)
{
if (e.Key == Key.Escape)
{
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;
}
}
}