/* * Copyright (c) 2025 LG Electronics Inc. * SPDX-License-Identifier: LicenseRef-LGE-Proprietary */ using Aurora; using Aurora.Api; using System; using System.Windows.Media; using System.Windows; using System.Windows.Controls; using VisionCommon; using Aurora.Api.DataType; using Cognex.VisionPro; using System.IO; using CogCommon; using System.Collections.Generic; using System.Reactive.Linq; using System.Threading.Tasks; using Cognex.VisionPro.Display; using System.Windows.Data; using System.Globalization; namespace CogUI { public partial class CameraView : UserControl, ICameraView, IDisposable { private Logger _Logger; private CameraBase _CameraDev; private CameraAgentBase _CameraAgent; private CamConfig _CamConfig; private eDisplayType _DisplayType; private ImageManager _ImageManager = new ImageManager(); private IDisposable _EventDisposable; private FovInfo _FovInfo; private FovRecipe _FovRecipe; private eCamId _CamId = eCamId.None; private eFovUiPos _FovUiPos = new eFovUiPos(); private SolidColorBrush BRUSH_STATE_ON = Brushes.LimeGreen; private SolidColorBrush BRUSH_STATE_OFF = Brushes.White; private List _GridModeBorders; private List _RulerModeBorders; #region Interface of ICameraView public int Row { get; set; } public int Col { get; set; } public MenuItem MenuShowCamWindow { get; set; } #endregion public CameraView(FovInfo fovInfo, eDisplayType displayType) { _FovInfo = fovInfo; _DisplayType = displayType; _FovRecipe = VisionRecipeManager.GetFovRecipe(_FovInfo); _Logger = new Logger(string.Format("CameraView[{0}]", _FovRecipe.FovName)); InitializeComponent(); Init(); SetObservable(); SetVisibility(); SetBorders(); _FovUiPos = VisionRecipeManager.GetFovUiPos(_FovRecipe, _DisplayType); CameraViewManager.Instance.SetSameUiPosFovInfos(_DisplayType, _FovUiPos, _FovInfo); CameraViewManager.Instance.SetCameraView(displayType, fovInfo, this); CameraDisplayManager.SetDisplay(displayType, fovInfo, cogCameraDisplay); CamLiveBtnManager.SetLiveBtnsForVisibility(displayType, fovInfo, btnLiveStart, btnLiveStop); } public FovInfo GetFovInfo() { return _FovInfo; } private void Init() { MenuShowCamWindow = menuShowCamWindow; _FovInfo = VisionRecipeManager.GetFovInfo(_FovInfo); if (_FovInfo == null) { return; // 레시피가 없으므로 무의미한 객체 } _FovRecipe = VisionRecipeManager.GetFovRecipe(_FovInfo); SetDataContext(); if (_CamId != _FovRecipe.CamRecipe.CamId) { _CamId = _FovRecipe.CamRecipe.CamId; _CameraDev = VisionEnv.AuroraEnv.DeviceManager[_CamId.ToString()] as CameraBase; _CameraAgent = CameraAgentManager.GetCameraAgent(_FovInfo); _CamConfig = VisionEnv.AuroraEnv.DeviceManager.GetDeviceConfig(_CamId.ToString()) as CamConfig; InitDisplayAndViewModel(); } } private void InitDisplayAndViewModel() { Application.Current.Dispatcher.Invoke( new Action(() => { cogCameraDisplay.Dispose(); cogCameraDisplay.Init(_CameraDev, _DisplayType, _CamConfig, _FovInfo, _FovRecipe); (DataContext as CameraViewModel).Init(_FovInfo, cogCameraDisplay); })); } private void SetObservable() { if (_EventDisposable == null) { var observable = VisionEventId.GetRecipeUpdateObservable(); _EventDisposable = observable.Subscribe(_ => Init()); } } private void SetVisibility() { if (!CamCommon.IsMainType(_DisplayType)) { btnSwitchCamView.Visibility = Visibility.Collapsed; menuShowCamWindow.Visibility = Visibility.Collapsed; } } public void SetButtonBarVisibility(bool isVisible) { if (isVisible) { spButtonBar.Visibility = Visibility.Visible; } else { spButtonBar.Visibility = Visibility.Collapsed; } } public void SetDisplayName(string displayName) { Application.Current.Dispatcher.BeginInvoke( new System.Action(() => { tbDisplayName.Text = displayName; })); } private void SetBorders() { _GridModeBorders = new List() { bdGrid_Wide, bdGrid_Narrow, bdGrid_Wide_ErrRotation, bdGrid_Narrow_ErrRotation }; _RulerModeBorders = new List() { bdDistanceAndAngle, bdPosition, bdMovePosition, bdCircle }; } private void SetDataContext() { Application.Current.Dispatcher.Invoke( new Action(() => { this.DataContext = new CameraViewModel(_FovInfo, _DisplayType, GetDisplay() as CameraDisplay); })); } public ICameraDisplay GetDisplay() { return cogCameraDisplay; } private void OnGridMode_Wide(object sender, RoutedEventArgs e) { if (IsStateOn(bdGrid_Wide)) { SetGridModeStateOff(); cogCameraDisplay.ClearGridGuidLine(); return; } SetGridModeStateOn(bdGrid_Wide); cogCameraDisplay.SetWideGridGuideLine(); } private void OnGridMode_Narrow(object sender, RoutedEventArgs e) { if (IsStateOn(bdGrid_Narrow)) { SetGridModeStateOff(); cogCameraDisplay.ClearGridGuidLine(); return; } SetGridModeStateOn(bdGrid_Narrow); cogCameraDisplay.SetNarrowGridGuideLine(); } private void OnGridMode_Wide_ErrRotation(object sender, RoutedEventArgs e) { if (IsStateOn(bdGrid_Wide_ErrRotation)) { SetGridModeStateOff(); cogCameraDisplay.ClearGridGuidLine(); return; } SetGridModeStateOn(bdGrid_Wide_ErrRotation); cogCameraDisplay.SetWideGridGuideLine_ErrRotation(); } private void OnGridMode_Narrow_ErrRotation(object sender, RoutedEventArgs e) { if (IsStateOn(bdGrid_Narrow_ErrRotation)) { SetGridModeStateOff(); cogCameraDisplay.ClearGridGuidLine(); return; } SetGridModeStateOn(bdGrid_Narrow_ErrRotation); cogCameraDisplay.SetNarrowGridGuideLine_ErrRotation(); } private void OnRulerMode_DistanceAndAngle(object sender, RoutedEventArgs e) { if (IsStateOn(bdDistanceAndAngle)) { SetRulerModeStateOff(); cogCameraDisplay.RulerModeOff(); return; } SetRulerModeStateOn(bdDistanceAndAngle); cogCameraDisplay.RulerModeOn(eDisplayMode.DistanceAngle); } private void OnRulerMode_Position(object sender, RoutedEventArgs e) { if (IsStateOn(bdPosition)) { SetRulerModeStateOff(); cogCameraDisplay.RulerModeOff(); return; } SetRulerModeStateOn(bdPosition); cogCameraDisplay.RulerModeOn(eDisplayMode.Position); } private void OnRulerMode_Circle(object sender, RoutedEventArgs e) { if (IsStateOn(bdCircle)) { SetRulerModeStateOff(); cogCameraDisplay.RulerModeOff(); return; } SetRulerModeStateOn(bdCircle); cogCameraDisplay.RulerModeOn(eDisplayMode.Circle); } private void OnRulerMode_MovePosition(object sender, RoutedEventArgs e) { if (IsStateOn(bdMovePosition)) { SetRulerModeStateOff(); cogCameraDisplay.RulerModeOff(); return; } SetRulerModeStateOn(bdMovePosition); cogCameraDisplay.RulerModeOn(eDisplayMode.MovePosition); } private void OnRulerMode_Clear(object sender, RoutedEventArgs e) { //cogCameraDisplay.RulerModeOff(); cogCameraDisplay.ClearAllGraphics(); } private bool IsStateOn(Border border) { return border.Background == BRUSH_STATE_ON; } private bool IsStateOff(Border border) { return border.Background == BRUSH_STATE_OFF; } private void SetGridModeStateOn(Border curBorder) { SetStateOn(_GridModeBorders, curBorder); } private void SetGridModeStateOff() { SetStateOff(_GridModeBorders); } private void SetRulerModeStateOn(Border curBorder) { SetStateOn(_RulerModeBorders, curBorder); } private void SetRulerModeStateOff() { SetStateOff(_RulerModeBorders); } private void SetStateOn(List borders, Border curBorder) { foreach (var bd in borders) { bd.Background = BRUSH_STATE_OFF; } curBorder.Background = BRUSH_STATE_ON; } private void SetStateOff(List borders) { foreach (var bd in borders) { bd.Background = BRUSH_STATE_OFF; } } private void OnLoadImage(object sender, RoutedEventArgs e) { string filePath = GetLoadFilePath(); if (filePath != string.Empty) { ICogImage image = (ICogImage)_ImageManager.LoadImage(filePath, _CamConfig); cogCameraDisplay.SetImage(image); cogCameraDisplay.ClearMeasureGraphics(); } } private string GetLoadFilePath() { try { var openFileDialog = new System.Windows.Forms.OpenFileDialog(); openFileDialog.Multiselect = false; openFileDialog.Filter = "Image files (*.png;*.bmp;*.jpeg;*.jpg)|*.png;*.bmp;*.jpeg;*.jpg|All files (*.*)|*.*"; openFileDialog.InitialDirectory = ImagePathManager.GetRootDirPath(); if (openFileDialog.ShowDialog() == System.Windows.Forms.DialogResult.OK) { return openFileDialog.FileName; } } catch (Exception e) { _Logger.FuncE(e.Message); } return ""; } private async void OnSaveImage(object sender, RoutedEventArgs e) { ICogImage image = cogCameraDisplay.GetImage(); string dirFilePath = GetSaveFilePath(VisionSettingManager.VisionSetting.ImageFormat); if (dirFilePath == string.Empty) { return; } await Task.Run(() => { CogEnvironment.SaveImage(dirFilePath, image); }); } private async void OnSaveOverlay(object sender, RoutedEventArgs e) { string dirFilePath = GetSaveFilePath(eImageFormat.JPG); if (dirFilePath == string.Empty) { return; } await Task.Run(() => { System.Drawing.Bitmap overlayImage = null; try { overlayImage = CogEnvironment.GetOverlayImage(cogCameraDisplay); if (overlayImage != null) { CogEnvironment.SaveImage(dirFilePath, overlayImage, eImageFormat.JPG); } } catch (Exception ex) { _Logger.E(ex.Message); } finally { overlayImage.Dispose(); } }); } private string GetSaveFilePath(eImageFormat defaultImageFormat) { try { var saveFileDialog = new System.Windows.Forms.SaveFileDialog(); saveFileDialog.RestoreDirectory = true; saveFileDialog.Filter = "Image files (*.png;*.bmp;*.jpg)|*.png;*.bmp;*.jpg|All files (*.*)|*.*"; saveFileDialog.InitialDirectory = ImagePathManager.GetRootDirPath(); saveFileDialog.DefaultExt = "." + defaultImageFormat.ToString().ToLower(); saveFileDialog.FileName = DateTime.Now.ToString("yyyy_MM_dd_HH_mm_ss") + "_" + _FovInfo.SubSysName + "_" + _FovRecipe.CamRecipe.CamId; if (saveFileDialog.ShowDialog() == System.Windows.Forms.DialogResult.OK) { if (File.Exists(saveFileDialog.FileName)) { File.Delete(saveFileDialog.FileName); } return saveFileDialog.FileName; } } catch (Exception e) { _Logger.FuncE(e.Message); } return ""; } public void SetImage(ICogImage image) { cogCameraDisplay.SetImage(image); } private void OnFitImage(object sender, RoutedEventArgs e) { (DataContext as CameraViewModel).DoFitImage(null); } private void OnShowCamWindow(object sender, RoutedEventArgs e) { (DataContext as CameraViewModel).DoShowCamWindow(null); } private void UserControl_IsVisibleChanged(object sender, DependencyPropertyChangedEventArgs e) { bool isVisible = (bool)e.NewValue; if (isVisible == true) { } else { if (!CamCommon.IsMainType(_DisplayType)) { _CameraAgent.StopLive(); } } } public void Dispose() { CameraViewManager.Instance.Remove(_DisplayType, _FovUiPos, _FovInfo); Application.Current.Dispatcher.BeginInvoke( new Action(() => { cogCameraDisplay?.Dispose(); cogCameraDisplay = null; (DataContext as CameraViewModel)?.Dispose(); DataContext = null; RemoveObservable(); })); } private void RemoveObservable() { _EventDisposable?.Dispose(); _EventDisposable = null; } } public class ViewTypeToVisibilityConverter : IMultiValueConverter { public object Convert(object[] value, Type targetType, object parameter, CultureInfo culture) { bool isCollapsed = true; if (value[0].GetType().IsValueType) { isCollapsed = (bool)value[0]; } double actualWidth = Double.Parse(value[1].ToString()); string viewType = value[2].ToString(); if (actualWidth > 300) { if (viewType == "DisplayName" || viewType == "Buttons") { return Visibility.Visible; } else { return Visibility.Collapsed; } } else { if (isCollapsed) { if (viewType == "DisplayName" || viewType == "ExpandBtn") { return Visibility.Visible; } else { return Visibility.Collapsed; } } else { if (viewType == "DisplayName" || viewType == "ExpandBtn") { return Visibility.Collapsed; } else { return Visibility.Visible; } } } } public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture) { throw new NotImplementedException(); } } }