diff --git a/CtrEditor.csproj b/CtrEditor.csproj
index b9c0c5b..92df0d6 100644
--- a/CtrEditor.csproj
+++ b/CtrEditor.csproj
@@ -68,9 +68,11 @@
-
+
+
+
@@ -116,6 +118,15 @@
SettingsSingleFileGenerator
Settings.Designer.cs
+
+ PreserveNewest
+
+
+ PreserveNewest
+
+
+ PreserveNewest
+
diff --git a/ObjetosSim/Extraccion Datos/ucExtraccionTag.xaml b/ObjetosSim/Extraccion Datos/ucExtraccionTag.xaml
new file mode 100644
index 0000000..1ff145e
--- /dev/null
+++ b/ObjetosSim/Extraccion Datos/ucExtraccionTag.xaml
@@ -0,0 +1,26 @@
+
+
+
+
+
+
+
+
diff --git a/ObjetosSim/Extraccion Datos/ucExtraccionTag.xaml.cs b/ObjetosSim/Extraccion Datos/ucExtraccionTag.xaml.cs
new file mode 100644
index 0000000..a8749ed
--- /dev/null
+++ b/ObjetosSim/Extraccion Datos/ucExtraccionTag.xaml.cs
@@ -0,0 +1,247 @@
+using System.Windows;
+using System.Windows.Controls;
+using System.Windows.Media.Animation;
+using System.Windows.Media;
+using CommunityToolkit.Mvvm.ComponentModel;
+
+using CtrEditor.Siemens;
+using CtrEditor.Simulacion;
+using System.Windows.Input;
+using System.IO;
+using System.Windows.Media.Imaging;
+using Tesseract;
+
+
+namespace CtrEditor.ObjetosSim.Extraccion_Datos
+{
+ ///
+ /// Interaction logic for ucExtraccionTag.xaml
+ ///
+ ///
+
+ public partial class osExtraccionTag : osBase, IosBase
+ {
+ private osBase _osMotor = null;
+
+ private simTransporte SimGeometria;
+
+ public static string NombreClase()
+ {
+ return "Extraccion Tags";
+ }
+ private string nombre = NombreClase();
+ public override string Nombre
+ {
+ get => nombre;
+ set => SetProperty(ref nombre, value);
+ }
+
+ [ObservableProperty]
+ bool extraer;
+
+ public override void TopChanged(float value)
+ {
+ base.TopChanged(value);
+ ResetTimer();
+ }
+
+ public override void LeftChanged(float value)
+ {
+ base.LeftChanged(value);
+ ResetTimer();
+ }
+
+ partial void OnExtraerChanged(bool value)
+ {
+ ResetTimer();
+ }
+
+ [ObservableProperty]
+ public float ancho;
+
+ partial void OnAnchoChanged(float value)
+ {
+ ResetTimer();
+ }
+
+ [ObservableProperty]
+ public float alto;
+
+ partial void OnAltoChanged(float value)
+ {
+ ResetTimer();
+ }
+
+ public override void OnTimerAfterMovement() {
+ if (Extraer)
+ CaptureImageAreaAndDoOCR();
+ }
+
+ [ObservableProperty]
+ public int n_Repeat_X;
+
+ [ObservableProperty]
+ public int n_Repeat_Y;
+
+ [ObservableProperty]
+ public float offset_Repeat_X;
+
+ [ObservableProperty]
+ public float offset_Repeat_Y;
+
+ [ObservableProperty]
+ public float angulo;
+
+ [ObservableProperty]
+ string tag_extract;
+
+ [ObservableProperty]
+ string clase;
+
+ [ObservableProperty]
+ string tag_name;
+
+ public osExtraccionTag()
+ {
+ Ancho = 1;
+ Alto = 1;
+ Angulo = 0;
+ }
+
+ private void ShowPreviewWindow(Stream imageStream)
+ {
+ // Create a new window for preview
+ Window previewWindow = new Window
+ {
+ Title = "Preview Captured Image",
+ Width = 500,
+ Height = 500,
+ Content = new Image
+ {
+ Source = BitmapFrame.Create(imageStream, BitmapCreateOptions.None, BitmapCacheOption.OnLoad),
+ Stretch = Stretch.Uniform
+ }
+ };
+
+ previewWindow.ShowDialog();
+ }
+
+ private void CaptureImageAreaAndDoOCR()
+ {
+ if (_mainViewModel?.MainCanvas.Children[0] is Image imagenDeFondo)
+ {
+ // Asegurarse de que la imagen origen está disponible
+ if (imagenDeFondo.Source is BitmapSource bitmapSource)
+ {
+ // Obtener los DPI de la imagen original
+ float originalDpiX = (float) bitmapSource.DpiX;
+ float originalDpiY = (float) bitmapSource.DpiY;
+
+ // Estándar DPI en el que el Canvas renderiza la imagen
+ float canvasDpiX = 96; // WPF usually renders at 96 DPI
+ float canvasDpiY = 96;
+
+ // Calcular el ratio de escala entre el Canvas y la imagen original
+ float scaleFactorX = originalDpiX / canvasDpiX;
+ float scaleFactorY = originalDpiY / canvasDpiY;
+
+ // Ajustar las coordenadas de recorte en función del ratio de escala
+ int x = (int)MeterToPixels(Left * scaleFactorX);
+ int y = (int)MeterToPixels(Top * scaleFactorY);
+ int width = (int)MeterToPixels(Ancho * scaleFactorX);
+ int height = (int)MeterToPixels(Alto * scaleFactorY);
+
+ // Validar y ajustar el tamaño del recorte para que se mantenga dentro de los límites de la imagen
+ if (x < 0) x = 0;
+ if (y < 0) y = 0;
+ if (x + width > bitmapSource.PixelWidth) width = bitmapSource.PixelWidth - x;
+ if (y + height > bitmapSource.PixelHeight) height = bitmapSource.PixelHeight - y;
+
+ // Recortar el área deseada utilizando las coordenadas ajustadas
+ CroppedBitmap croppedBitmap = new CroppedBitmap(bitmapSource, new Int32Rect(x, y, width, height));
+
+ // Codificar el bitmap recortado a un MemoryStream
+ PngBitmapEncoder encoder = new PngBitmapEncoder();
+ encoder.Frames.Add(BitmapFrame.Create(croppedBitmap));
+
+ using (MemoryStream memoryStream = new MemoryStream())
+ {
+ encoder.Save(memoryStream);
+ memoryStream.Seek(0, SeekOrigin.Begin);
+
+ // Mostrar la imagen recortada en una ventana de previsualización
+ // ShowPreviewWindow(memoryStream);
+
+ // Cargar la imagen en Tesseract desde el MemoryStream
+ using (var img = Pix.LoadFromMemory(memoryStream.ToArray()))
+ using (var engine = new TesseractEngine(@"./Tesseract", "eng", EngineMode.Default))
+ {
+ var result = engine.Process(img);
+ Tag_extract = result.GetText();
+ }
+ }
+ }
+ }
+ }
+
+ public override void ucLoaded()
+ {
+ // El UserControl ya se ha cargado y podemos obtener las coordenadas para
+ // crear el objeto de simulacion
+ base.ucLoaded();
+
+ }
+
+ }
+
+ public partial class ucExtraccionTag : UserControl, IDataContainer
+ {
+ public osBase? Datos { get; set; }
+
+ public ucExtraccionTag()
+ {
+ InitializeComponent();
+ this.Loaded += OnLoaded;
+ this.Unloaded += OnUnloaded;
+ }
+ private void OnLoaded(object sender, RoutedEventArgs e)
+ {
+ Datos?.ucLoaded();
+ }
+ private void OnUnloaded(object sender, RoutedEventArgs e)
+ {
+ Datos?.ucUnLoaded();
+ }
+ public void Resize(float width, float height)
+ {
+ if (Datos is osExtraccionTag datos)
+ {
+ datos.Ancho = PixelToMeter.Instance.calc.PixelsToMeters(width);
+ datos.Alto = PixelToMeter.Instance.calc.PixelsToMeters(height);
+ }
+ }
+ public void Move(float LeftPixels, float TopPixels)
+ {
+ if (Datos != null)
+ {
+ Datos.Left = PixelToMeter.Instance.calc.PixelsToMeters(LeftPixels);
+ Datos.Top = PixelToMeter.Instance.calc.PixelsToMeters(TopPixels);
+ }
+ }
+ public void Rotate(float Angle)
+ {
+ if (Datos != null)
+ if (Datos is osExtraccionTag datos)
+ datos.Angulo = Angle;
+ }
+ public void Highlight(bool State) { }
+ public int ZIndex()
+ {
+ return 1;
+ }
+
+ }
+}
+
+
+
diff --git a/ObjetosSim/osBase.cs b/ObjetosSim/osBase.cs
index 6dab284..1d19550 100644
--- a/ObjetosSim/osBase.cs
+++ b/ObjetosSim/osBase.cs
@@ -13,6 +13,8 @@ using System.Diagnostics;
using System.Windows.Shapes;
using System.Windows.Controls;
using System.ComponentModel;
+using System.Configuration;
+using System.Windows.Threading;
namespace CtrEditor.ObjetosSim
{
@@ -59,7 +61,8 @@ namespace CtrEditor.ObjetosSim
public virtual string Nombre { get; set; } = "osBase";
[JsonIgnore]
private Storyboard _storyboard;
-
+ private System.Threading.Timer timer = null;
+
[ObservableProperty]
private float left;
@@ -96,6 +99,26 @@ namespace CtrEditor.ObjetosSim
public virtual void TopChanged(float value) { }
public virtual void TopChanging(float oldValue, float newValue) { }
+ private async void TimerCallback(object state)
+ {
+ await Task.Delay(500); // Esperar 0.5 segundos antes de ejecutar la función
+ Application.Current.Dispatcher.Invoke(() =>
+ {
+ // Realiza tus cambios en la interfaz de usuario aquí
+ OnTimerAfterMovement();
+ });
+ }
+
+ public void ResetTimer()
+ {
+ if (timer == null)
+ timer = new System.Threading.Timer(TimerCallback, null, Timeout.Infinite, Timeout.Infinite);
+
+ timer.Change(500, Timeout.Infinite);
+ }
+
+ public virtual void OnTimerAfterMovement() { }
+
///
/// Usado para saber cuando un objeto fue creado manualmente o por algun generador
/// Mas adelante la idea es poder eliminar o tratar de manera diferente a estos objetos
diff --git a/ObjetosSim/ucBasicExample.xaml b/ObjetosSim/ucBasicExample.xaml
index 7b050ee..5c43d60 100644
--- a/ObjetosSim/ucBasicExample.xaml
+++ b/ObjetosSim/ucBasicExample.xaml
@@ -7,23 +7,6 @@
xmlns:vm="clr-namespace:CtrEditor.ObjetosSim"
mc:Ignorable="d">
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/Tesseract/eng.traineddata b/Tesseract/eng.traineddata
new file mode 100644
index 0000000..bbef467
Binary files /dev/null and b/Tesseract/eng.traineddata differ
diff --git a/Tesseract/ita.traineddata b/Tesseract/ita.traineddata
new file mode 100644
index 0000000..edbffbe
Binary files /dev/null and b/Tesseract/ita.traineddata differ
diff --git a/Tesseract/spa.traineddata b/Tesseract/spa.traineddata
new file mode 100644
index 0000000..72e901f
Binary files /dev/null and b/Tesseract/spa.traineddata differ