2026-01-26 14:51:28 +09:00

444 lines
16 KiB
C#

/*
* 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<Border> _GridModeBorders;
private List<Border> _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<Border>() { bdGrid_Wide, bdGrid_Narrow, bdGrid_Wide_ErrRotation, bdGrid_Narrow_ErrRotation };
_RulerModeBorders = new List<Border>() { 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<Border> borders, Border curBorder) {
foreach (var bd in borders) {
bd.Background = BRUSH_STATE_OFF;
}
curBorder.Background = BRUSH_STATE_ON;
}
private void SetStateOff(List<Border> 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();
}
}
}