ROIEditor/MainWindow.xaml.cs

557 lines
21 KiB
C#
Raw Normal View History

2024-04-14 04:47:56 -03:00
using System.IO;
2024-04-11 06:51:12 -03:00
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
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
2024-04-12 18:06:46 -03:00
2024-04-11 06:51:12 -03:00
private Point? clickPosition = null;
private bool _isDrawing = false;
2024-04-14 04:47:56 -03:00
private bool _EstaCargandoTrabajo = false;
2024-04-11 06:51:12 -03:00
private Point _startPosition;
private Rectangle _currentRect = null;
private Image imagenDeFondo;
private bool _isDragging = false;
private Point _lastMousePosition;
2024-04-14 04:47:56 -03:00
private ListaPersistente<Roi> ListaDeROIs;
private ItemPersistente<ImagenEstado> EstadoImagenActual;
private EstadoTrabajo Estado;
2024-04-11 06:51:12 -03:00
// Constructor de MainWindow
public MainWindow()
{
InitializeComponent();
2024-04-14 04:47:56 -03:00
this.Closing += MainWindow_Closing; // Suscribir al evento Closing
2024-04-11 06:51:12 -03:00
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;
2024-04-12 19:55:02 -03:00
Borrar_ROI.Click += Borrar_ROI_Click;
2024-04-11 06:51:12 -03:00
// Suscripción a los eventos LostFocus
ROI_xy.LostFocus += GuardarCambiosRoi;
2024-04-15 08:38:56 -03:00
ROI_dxdy.LostFocus += GuardarCambiosRoi;
2024-04-11 06:51:12 -03:00
ROI_descripcion.LostFocus += GuardarCambiosRoi;
2024-04-14 04:47:56 -03:00
// Se carga el ultimo estado
Estado = EstadoTrabajo.CargarEstado();
DirectorioTrabajo.Text = Estado.strDirectorioTrabajo;
ActualizarPorCambioDirTrabajo();
}
private void MainWindow_Closing(object sender, System.ComponentModel.CancelEventArgs e)
{
SalvarEstadoImgen_y_ROIs();
Estado.GuardarEstado(); // Guardar el estado cuando la ventana se cierra
}
private void SeleccionarDirectorio_Click(object sender, RoutedEventArgs e)
{
var dialog = new Ookii.Dialogs.Wpf.VistaFolderBrowserDialog();
if (dialog.ShowDialog(this).GetValueOrDefault())
{
DirectorioTrabajo.Text = dialog.SelectedPath;
if (Estado.strDirectorioTrabajo != DirectorioTrabajo.Text)
{
Estado.strDirectorioTrabajo = DirectorioTrabajo.Text;
ActualizarPorCambioDirTrabajo();
}
}
}
private void LeerDirectorio_Click(object sender, RoutedEventArgs e)
{
ActualizarPorCambioDirTrabajo();
2024-04-11 06:51:12 -03:00
}
2024-04-14 04:47:56 -03:00
private void ActualizarPorCambioDirTrabajo()
{
string dbPath = Estado.CarpetaDB();
_EstaCargandoTrabajo = true;
ListaDeROIs = new ListaPersistente<Roi>(dbPath, "ROIs");
EstadoImagenActual = new ItemPersistente<ImagenEstado>(dbPath, "estados");
CargarImagenes();
if (!string.IsNullOrEmpty(Estado.NombreImagenEditando))
{
for (int i = 0; i < ListaImagenes.Items.Count; i++)
{
if ((string)ListaImagenes.Items[i] == Estado.NombreImagenEditando)
{
ListaImagenes.SelectedIndex = i; // Selecciona el ítem que coincide con el último editado
break;
}
}
}
_EstaCargandoTrabajo = false;
}
2024-04-12 19:55:02 -03:00
2024-04-11 06:51:12 -03:00
private void ListaROIs_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
if (ListaROIs.SelectedItem is Roi selectedRoi)
{
CargarDatosROI(selectedRoi);
}
}
2024-04-12 19:55:02 -03:00
private void Borrar_ROI_Click(object sender, RoutedEventArgs e)
2024-04-11 06:51:12 -03:00
{
if (ListaROIs.SelectedItem is Roi selectedRoi)
{
2024-04-12 19:55:02 -03:00
ListaDeROIs.Remove(selectedRoi);
ActualizarListaROIsEnUI();
}
}
private void Guardar_ROI_Click(object sender, RoutedEventArgs e)
{
if (ListaROIs.SelectedItem is Roi selectedRoi)
{
2024-04-11 06:51:12 -03:00
ActualizarDatosROI(selectedRoi);
}
}
private void CargarDatosROI(Roi selectedRoi)
{
ROI_xy.Text = $"{selectedRoi.X}, {selectedRoi.Y}";
ROI_dxdy.Text = $"{selectedRoi.Width}, {selectedRoi.Height}";
ROI_descripcion.Text = selectedRoi.Descripcion;
2024-04-15 08:38:56 -03:00
for (int i = 0; i < ROI_imagen.Items.Count; i++)
{
if ((string)ROI_imagen.Items[i] == Estado.NombreImagenEditando)
{
ROI_imagen.SelectedIndex = i; // Selecciona el ítem que coincide con el último editado
break;
}
}
2024-04-11 06:51:12 -03:00
}
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.Descripcion = ROI_descripcion.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);
2024-04-12 19:55:02 -03:00
// Si se modificaron las coordenadas
DibujarROIsEnCanvas();
2024-04-11 06:51:12 -03:00
}
}
private void CargarImagenes()
{
// Asumiendo que las imágenes están en una carpeta "Imagenes" dentro del directorio de salida de tu aplicación
2024-04-15 08:38:56 -03:00
string folderPath = Estado.PNG_Folther_Path();
2024-04-11 06:51:12 -03:00
if (Directory.Exists(folderPath))
{
var archivosImagen = Directory.GetFiles(folderPath, "*.png"); // Asumiendo que buscas archivos .png
2024-04-15 08:38:56 -03:00
ListaImagenes.Items.Clear();
ROI_imagen.Items.Clear();
2024-04-11 06:51:12 -03:00
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));
2024-04-15 08:38:56 -03:00
ROI_imagen.Items.Add(Path.GetFileName(archivo));
2024-04-11 06:51:12 -03:00
}
}
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
2024-04-12 18:06:46 -03:00
Roi newRoi = new Roi(EstadoImagenActual.Get().NombreImagen, (int)x, (int)y, (int)width, (int)height);
2024-04-11 06:51:12 -03:00
// 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
2024-04-12 19:55:02 -03:00
ActualizarListaROIsEnUI();
2024-04-11 06:51:12 -03:00
}
}
}
2024-04-12 19:55:02 -03:00
private void ActualizarListaROIsEnUI()
2024-04-11 06:51:12 -03:00
{
// 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;
2024-04-12 18:06:46 -03:00
if (ListaDeROIs.Count > 0)
2024-04-11 06:51:12 -03:00
{
2024-04-12 18:06:46 -03:00
ListaROIs.ItemsSource = ListaDeROIs.GetList();
2024-04-11 06:51:12 -03:00
}
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);
}
2024-04-15 08:38:56 -03:00
2024-04-11 06:51:12 -03:00
private void ListaImagenes_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
2024-04-14 04:47:56 -03:00
2024-04-11 06:51:12 -03:00
if (ListaImagenes.SelectedItem != null)
{
2024-04-14 04:47:56 -03:00
SalvarEstadoImgen_y_ROIs();
2024-04-11 06:51:12 -03:00
2024-04-14 04:47:56 -03:00
Estado.NombreImagenEditando = ListaImagenes.SelectedItem.ToString();
ListaDeROIs.Load(Estado.NombreImagenEditando);
2024-04-12 19:55:02 -03:00
ActualizarListaROIsEnUI();
2024-04-15 08:38:56 -03:00
CargarImagenEnTrabajo(Estado.PNG_Extension_Path());
2024-04-11 06:51:12 -03:00
CargarEstadoImagen();
}
}
2024-04-14 04:47:56 -03:00
private void SalvarEstadoImgen_y_ROIs()
{
if (!_EstaCargandoTrabajo)
{
// Si es igual es porque es la primera vez que se carga
if (Estado.NombreImagenEditando != null)
{
SalvarEstadoImagen();
}
if (ListaDeROIs.Count > 0)
{
ListaDeROIs.Save();
}
}
}
2024-04-11 06:51:12 -03:00
private void CargarEstadoImagen()
{
2024-04-12 18:06:46 -03:00
var st = (ScaleTransform)ImagenEnTrabajoCanvas.LayoutTransform;
2024-04-14 04:47:56 -03:00
if (EstadoImagenActual.Load(Estado.NombreImagenEditando))
2024-04-11 06:51:12 -03:00
{
2024-04-12 18:06:46 -03:00
var EACargado = EstadoImagenActual.Get();
2024-04-11 06:51:12 -03:00
2024-04-12 18:06:46 -03:00
st.ScaleX = EACargado.ZoomScaleX;
st.ScaleY = EACargado.ZoomScaleY;
2024-04-11 06:51:12 -03:00
// Aplicar el nuevo desplazamiento
2024-04-12 18:06:46 -03:00
ImagenEnTrabajoScrollViewer.ScrollToHorizontalOffset(EACargado.HorizontalOffset);
ImagenEnTrabajoScrollViewer.ScrollToVerticalOffset(EACargado.VerticalOffset);
2024-04-11 06:51:12 -03:00
2024-04-12 18:06:46 -03:00
DibujarROIsEnCanvas();
}
else
2024-04-11 06:51:12 -03:00
{
2024-04-12 18:06:46 -03:00
var EANuevo = EstadoImagenActual.Get();
EANuevo.NombreImagen = ListaImagenes.SelectedItem.ToString();
EANuevo.ZoomScaleX = st.ScaleX;
EANuevo.ZoomScaleY = st.ScaleY;
EANuevo.HorizontalOffset = EANuevo.HorizontalOffset;
EANuevo.VerticalOffset = EANuevo.VerticalOffset;
2024-04-11 06:51:12 -03:00
}
2024-04-12 18:06:46 -03:00
2024-04-11 06:51:12 -03:00
}
private void SalvarEstadoImagen()
{
2024-04-12 18:06:46 -03:00
var ea = EstadoImagenActual.Get();
2024-04-11 06:51:12 -03:00
var st = (ScaleTransform)ImagenEnTrabajoCanvas.LayoutTransform;
2024-04-12 18:06:46 -03:00
ea.ZoomScaleX = st.ScaleX;
ea.ZoomScaleY = st.ScaleY;
ea.HorizontalOffset = ImagenEnTrabajoScrollViewer.HorizontalOffset;
ea.VerticalOffset = ImagenEnTrabajoScrollViewer.VerticalOffset;
2024-04-11 06:51:12 -03:00
2024-04-14 04:47:56 -03:00
EstadoImagenActual.Save(Estado.NombreImagenEditando);
2024-04-11 06:51:12 -03:00
}
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
2024-04-12 18:06:46 -03:00
foreach (var roi in ListaDeROIs.GetList())
2024-04-11 06:51:12 -03:00
{
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)
{
2024-04-12 18:06:46 -03:00
int index = ListaDeROIs.IndexOf(roi);
2024-04-11 06:51:12 -03:00
if (index != -1)
{
ListaROIs.SelectedIndex = index; // Selecciona el ROI en la lista
e.Handled = true; // Evita la propagación del evento
}
}
}
}
}