using Newtonsoft.Json; using System.Diagnostics.Eventing.Reader; using System.IO; using System.Text; using System.Windows; using System.Windows.Controls; using System.Windows.Data; using System.Windows.Documents; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Imaging; using System.Windows.Navigation; using System.Windows.Shapes; using Path = System.IO.Path; namespace ROIEditor { /// /// Interaction logic for MainWindow.xaml /// public partial class MainWindow : Window { private ImagenEstado EstadoImagenActual = new ImagenEstado(); private Point? clickPosition = null; private bool _isDrawing = false; private Point _startPosition; private Rectangle _currentRect = null; private Image imagenDeFondo; private bool _isDragging = false; private Point _lastMousePosition; public dbROIs ListaDeROIs = new dbROIs(); // Constructor de MainWindow public MainWindow() { InitializeComponent(); CargarImagenes(); ListaImagenes.SelectionChanged += ListaImagenes_SelectionChanged; ImagenEnTrabajoCanvas.MouseLeftButtonDown += ImagenEnTrabajoCanvas_MouseLeftButtonDown; ImagenEnTrabajoCanvas.MouseRightButtonDown += ImagenEnTrabajoCanvas_MouseRightButtonDown; ImagenEnTrabajoCanvas.MouseDown += Canvas_MouseDown; ImagenEnTrabajoCanvas.MouseMove += Canvas_MouseMove; ImagenEnTrabajoScrollViewer.PreviewMouseWheel += ImagenEnTrabajoCanvas_MouseWheel; // En el constructor de MainWindow o un método de inicialización ImagenEnTrabajoCanvas.MouseDown += Canvas_MouseDown_Panning; ImagenEnTrabajoCanvas.MouseMove += Canvas_MouseMove_Panning; ImagenEnTrabajoCanvas.MouseUp += Canvas_MouseUp_Panning; // Agrega este manejador en el inicializador de tu ventana o control ListaROIs.SelectionChanged += ListaROIs_SelectionChanged; // Agrega este manejador en el inicializador de tu ventana o control Guardar_ROI.Click += Guardar_ROI_Click; // Suscripción a los eventos LostFocus ROI_xy.LostFocus += GuardarCambiosRoi; ROI_dxdy.LostFocus += GuardarCambiosRoi; ROI_nombre.LostFocus += GuardarCambiosRoi; ROI_num.LostFocus += GuardarCambiosRoi; ROI_descripcion.LostFocus += GuardarCambiosRoi; ROI_text1.LostFocus += GuardarCambiosRoi; ROI_text2.LostFocus += GuardarCambiosRoi; ROI_text3.LostFocus += GuardarCambiosRoi; } private void ListaROIs_SelectionChanged(object sender, SelectionChangedEventArgs e) { if (ListaROIs.SelectedItem is Roi selectedRoi) { CargarDatosROI(selectedRoi); } } private void Guardar_ROI_Click(object sender, RoutedEventArgs e) { if (ListaROIs.SelectedItem is Roi selectedRoi) { ActualizarDatosROI(selectedRoi); } } private void CargarDatosROI(Roi selectedRoi) { ROI_xy.Text = $"{selectedRoi.X}, {selectedRoi.Y}"; ROI_dxdy.Text = $"{selectedRoi.Width}, {selectedRoi.Height}"; ROI_nombre.Text = selectedRoi.Nombre; ROI_num.Text = selectedRoi.CodigoNumerico.ToString(); ROI_descripcion.Text = selectedRoi.Descripcion; ROI_text1.Text = selectedRoi.CampoTexto1; ROI_text2.Text = selectedRoi.CampoTexto2; ROI_text3.Text = selectedRoi.CampoTexto3; } private void ActualizarDatosROI(Roi selectedRoi) { try { // Suponiendo que se validen y parseen adecuadamente los valores var xy = ROI_xy.Text.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries); var dxdy = ROI_dxdy.Text.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries); selectedRoi.X = int.Parse(xy[0].Trim()); selectedRoi.Y = int.Parse(xy[1].Trim()); selectedRoi.Width = int.Parse(dxdy[0].Trim()); selectedRoi.Height = int.Parse(dxdy[1].Trim()); selectedRoi.Nombre = ROI_nombre.Text; selectedRoi.CodigoNumerico = int.TryParse(ROI_num.Text, out int codigo) ? codigo : 0; selectedRoi.Descripcion = ROI_descripcion.Text; selectedRoi.CampoTexto1 = ROI_text1.Text; selectedRoi.CampoTexto2 = ROI_text2.Text; selectedRoi.CampoTexto3 = ROI_text3.Text; // Aquí podrías llamar a un método que realice el guardado específico, si es necesario // Por ejemplo, actualizar la visualización del ROI o guardar en un archivo JSON } catch (Exception ex) { // Manejar posibles errores de parseo o validación MessageBox.Show($"Error al actualizar los datos del ROI: {ex.Message}"); } } private void GuardarCambiosRoi(object sender, RoutedEventArgs e) { if (ListaROIs.SelectedItem is Roi selectedRoi) { ActualizarDatosROI(selectedRoi); } } private void CargarImagenes() { // Asumiendo que las imágenes están en una carpeta "Imagenes" dentro del directorio de salida de tu aplicación string folderPath = Path.Combine(Directory.GetCurrentDirectory(), "Plantillas"); if (Directory.Exists(folderPath)) { var archivosImagen = Directory.GetFiles(folderPath, "*.png"); // Asumiendo que buscas archivos .png foreach (var archivo in archivosImagen) { // Aquí simplemente añadimos el nombre del archivo a la lista, pero podrías querer añadir un objeto más complejo ListaImagenes.Items.Add(Path.GetFileName(archivo)); } } else { MessageBox.Show("No se encontró la carpeta de imágenes."); } } private void Canvas_MouseDown_Panning(object sender, MouseButtonEventArgs e) { if (e.LeftButton == MouseButtonState.Pressed && !_isDrawing) { // Indica que se inicia el panning _isDragging = true; // Guarda la posición actual del ratón _lastMousePosition = e.GetPosition(ImagenEnTrabajoScrollViewer); //ImagenEnTrabajoScrollViewer.CaptureMouse(); // Importante para capturar el movimiento } } private void Canvas_MouseMove_Panning(object sender, MouseEventArgs e) { if (_isDragging && !_isDrawing) { // Calcula el nuevo desplazamiento basado en el movimiento del ratón var currentPosition = e.GetPosition(ImagenEnTrabajoScrollViewer); var dx = currentPosition.X - _lastMousePosition.X; var dy = currentPosition.Y - _lastMousePosition.Y; // Ajusta el desplazamiento del ScrollViewer ImagenEnTrabajoScrollViewer.ScrollToHorizontalOffset(ImagenEnTrabajoScrollViewer.HorizontalOffset - dx); ImagenEnTrabajoScrollViewer.ScrollToVerticalOffset(ImagenEnTrabajoScrollViewer.VerticalOffset - dy); // Actualiza la posición del ratón para el próximo movimiento _lastMousePosition = currentPosition; } } private void Canvas_MouseUp_Panning(object sender, MouseButtonEventArgs e) { if (_isDragging) { _isDragging = false; ImagenEnTrabajoScrollViewer.ReleaseMouseCapture(); // Finaliza la captura del ratón } } private void Canvas_MouseDown(object sender, MouseButtonEventArgs e) { // Verifica si el botón derecho del ratón fue el que se presionó if (e.ChangedButton == MouseButton.Right) { if (!_isDrawing) { _startPosition = e.GetPosition(ImagenEnTrabajoCanvas); _isDrawing = true; // Inicializar un nuevo rectángulo _currentRect = new Rectangle { Stroke = Brushes.Red, StrokeThickness = 2, Fill = Brushes.Transparent }; Canvas.SetLeft(_currentRect, _startPosition.X); Canvas.SetTop(_currentRect, _startPosition.Y); ImagenEnTrabajoCanvas.Children.Add(_currentRect); } else { // Finaliza el dibujo del rectángulo _isDrawing = false; // Calcula las dimensiones finales y posición del ROI var endPosition = e.GetPosition(ImagenEnTrabajoCanvas); var x = Math.Min(_startPosition.X, endPosition.X); var y = Math.Min(_startPosition.Y, endPosition.Y); var width = Math.Abs(endPosition.X - _startPosition.X); var height = Math.Abs(endPosition.Y - _startPosition.Y); // Crea el nuevo objeto Roi con la información recopilada Roi newRoi = new Roi(EstadoImagenActual.NombreImagen, (int)x, (int)y, (int)width, (int)height); // Agrega el nuevo Roi a la lista de ROIs ListaDeROIs.Add(newRoi); // Elimina el rectángulo temporal del Canvas ImagenEnTrabajoCanvas.Children.Remove(_currentRect); _currentRect = null; // Actualiza la interfaz de usuario con el nuevo ROI ActualizarUIConROIs(); } } } private void ActualizarUIConROIs() { // Aquí actualizas los controles de la interfaz de usuario que muestran los ROIs // Por ejemplo, si tienes una ListBox para los ROIs, actualízala así: ListaROIs.ItemsSource = null; if (ListaDeROIs.Count() > 0) { ListaROIs.ItemsSource = ListaDeROIs.rois; } DibujarROIsEnCanvas(); } private void Canvas_MouseMove(object sender, MouseEventArgs e) { if (_isDrawing) { var currentPosition = e.GetPosition(ImagenEnTrabajoCanvas); var width = Math.Abs(currentPosition.X - _startPosition.X); var height = Math.Abs(currentPosition.Y - _startPosition.Y); _currentRect.Width = width; _currentRect.Height = height; // Ajusta la posición si el dibujo se hace hacia arriba o hacia la izquierda if (currentPosition.X < _startPosition.X) { Canvas.SetLeft(_currentRect, currentPosition.X); } if (currentPosition.Y < _startPosition.Y) { Canvas.SetTop(_currentRect, currentPosition.Y); } } } private void ImagenEnTrabajoCanvas_MouseWheel(object sender, MouseWheelEventArgs e) { var st = (ScaleTransform)ImagenEnTrabajoCanvas.LayoutTransform; double zoomFactor = e.Delta > 0 ? 1.1 : 0.9; Point cursorPosition = e.GetPosition(ImagenEnTrabajoScrollViewer); // Calcular el punto focal del zoom relativo al contenido del ScrollViewer var absoluteX = ImagenEnTrabajoScrollViewer.HorizontalOffset + cursorPosition.X; var absoluteY = ImagenEnTrabajoScrollViewer.VerticalOffset + cursorPosition.Y; // Aplicar el zoom st.ScaleX *= zoomFactor; st.ScaleY *= zoomFactor; // Calcular el nuevo desplazamiento para que el zoom se centre en la posición del cursor ImagenEnTrabajoScrollViewer.UpdateLayout(); // Asegurarse de que el layout del ScrollViewer esté actualizado var newHorizontalOffset = absoluteX * zoomFactor - cursorPosition.X; var newVerticalOffset = absoluteY * zoomFactor - cursorPosition.Y; // Aplicar el nuevo desplazamiento ImagenEnTrabajoScrollViewer.ScrollToHorizontalOffset(newHorizontalOffset); ImagenEnTrabajoScrollViewer.ScrollToVerticalOffset(newVerticalOffset); e.Handled = true; // Evita el procesamiento adicional del evento } private void ImagenEnTrabajoCanvas_MouseRightButtonDown(object sender, MouseButtonEventArgs e) { var mousePos = e.GetPosition(ImagenEnTrabajoCanvas); // Verificar si mousePos está dentro de algún ROI y mostrar el formulario de comentario si es así } private void ImagenEnTrabajoCanvas_MouseLeftButtonDown(object sender, MouseButtonEventArgs e) { var mousePos = e.GetPosition(ImagenEnTrabajoCanvas); // Aquí puedes inicializar la creación de un nuevo ROI basándote en mousePos } private void CargarImagenEnTrabajo(string imagePath) { BitmapImage bitmap = new BitmapImage(new Uri(imagePath, UriKind.Absolute)); if (imagenDeFondo == null) { imagenDeFondo = new Image(); ImagenEnTrabajoCanvas.Children.Add(imagenDeFondo); } imagenDeFondo.Source = bitmap; RenderOptions.SetBitmapScalingMode(imagenDeFondo, BitmapScalingMode.HighQuality); // Elimina solo los ROIs, no la imagen de fondo for (int i = ImagenEnTrabajoCanvas.Children.Count - 1; i >= 0; i--) { if (ImagenEnTrabajoCanvas.Children[i] is Rectangle) { ImagenEnTrabajoCanvas.Children.RemoveAt(i); } } // Ajusta el tamaño del Canvas a la imagen, si es necesario ImagenEnTrabajoCanvas.Width = bitmap.Width; ImagenEnTrabajoCanvas.Height = bitmap.Height; // Posiciona la imagen correctamente dentro del Canvas Canvas.SetLeft(imagenDeFondo, 0); Canvas.SetTop(imagenDeFondo, 0); } private void ListaImagenes_SelectionChanged(object sender, SelectionChangedEventArgs e) { if (ListaImagenes.SelectedItem != null) { if (EstadoImagenActual.NombreImagen != null) { SalvarEstadoImagen(); } if (ListaDeROIs.Count()>0) { ListaDeROIs.GuardarRois(); } EstadoImagenActual = new ImagenEstado(); EstadoImagenActual.NombreImagen = ListaImagenes.SelectedItem.ToString(); ListaDeROIs = new dbROIs(EstadoImagenActual.NombreImagen); var imagePath = EstadoImagenActual.PathPlantillasPNG(); CargarImagenEnTrabajo(imagePath); CargarEstadoImagen(); } } private void CargarEstadoImagen() { string jsonPath = EstadoImagenActual.PathPlantillasJson(); if (File.Exists(jsonPath)) { string json = File.ReadAllText(jsonPath); EstadoImagenActual = JsonConvert.DeserializeObject(json); var st = (ScaleTransform)ImagenEnTrabajoCanvas.LayoutTransform; st.ScaleX= EstadoImagenActual.ZoomScaleX ; st.ScaleY = EstadoImagenActual.ZoomScaleY; // Aplicar el nuevo desplazamiento ImagenEnTrabajoScrollViewer.ScrollToHorizontalOffset(EstadoImagenActual.HorizontalOffset); ImagenEnTrabajoScrollViewer.ScrollToVerticalOffset(EstadoImagenActual.VerticalOffset); DibujarROIsEnCanvas(); } else { var st = (ScaleTransform)ImagenEnTrabajoCanvas.LayoutTransform; EstadoImagenActual.ZoomScaleX = st.ScaleX; EstadoImagenActual.ZoomScaleY = st.ScaleY; EstadoImagenActual.HorizontalOffset = EstadoImagenActual.HorizontalOffset; EstadoImagenActual.VerticalOffset = EstadoImagenActual.VerticalOffset; } } private void SalvarEstadoImagen() { // Cambia la extensión del archivo de imagen a .json string jsonPath = EstadoImagenActual.PathPlantillasJson(); var st = (ScaleTransform)ImagenEnTrabajoCanvas.LayoutTransform; EstadoImagenActual.ZoomScaleX = st.ScaleX; EstadoImagenActual.ZoomScaleY = st.ScaleY; EstadoImagenActual.HorizontalOffset = ImagenEnTrabajoScrollViewer.HorizontalOffset; EstadoImagenActual.VerticalOffset = ImagenEnTrabajoScrollViewer.VerticalOffset; // Serializa el estado de la imagen a JSON string json = JsonConvert.SerializeObject(EstadoImagenActual, Formatting.Indented); // Escribe el JSON en un archivo File.WriteAllText(jsonPath, json); } private void DibujarROIsEnCanvas() { // Elimina solo los ROIs, no la imagen de fondo for (int i = ImagenEnTrabajoCanvas.Children.Count - 1; i >= 0; i--) { if (ImagenEnTrabajoCanvas.Children[i] is Rectangle) { ImagenEnTrabajoCanvas.Children.RemoveAt(i); } } // Dibuja los ROIs foreach (var roi in ListaDeROIs.rois) { Rectangle rect = roi.DibujarRoiEnCanvas(ImagenEnTrabajoCanvas); // Eventos rect.MouseEnter += Rect_MouseEnter; rect.MouseLeave += Rect_MouseLeave; rect.MouseDown += Rect_MouseDown; } } private void Rect_MouseEnter(object sender, MouseEventArgs e) { if (sender is Rectangle rect) { rect.StrokeThickness = 4; // Aumenta el grosor } } private void Rect_MouseLeave(object sender, MouseEventArgs e) { if (sender is Rectangle rect) { rect.StrokeThickness = 2; // Restaura el grosor } } private void Rect_MouseDown(object sender, MouseButtonEventArgs e) { if (sender is Rectangle rect && rect.Tag is Roi roi) { int index = ListaDeROIs.rois.IndexOf(roi); if (index != -1) { ListaROIs.SelectedIndex = index; // Selecciona el ROI en la lista e.Handled = true; // Evita la propagación del evento } } } } }