348 lines
13 KiB
C#
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;
|
|
}
|
|
}
|
|
} |