using DataEntity; using DataEntity.Share; using DataRWDAL; using HxSocket; using Newtonsoft.Json.Linq; using System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Configuration; using System.Data; using System.IO; using System.Linq; using System.Windows; using System.Windows.Controls; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Imaging; using System.Windows.Media.Media3D; using System.Xml; using XCommon.Image; using XCommon.Log; using XHandler.Class; using XHandler.Class.DataEx; using XHandler.Controls.DrawCanvas; using XHandler.View.ManualCoating; using XHandler.View.MethodProperty; using XImagingXhandler.XDAL; namespace XHandler.View.ManualPick { /// /// 手动挑菌页面 /// public partial class ManualPickBacteria : Window { #region 变量 private string srcImageFile; private string jsonFile; private double startZoom; private string bacteriaTypeID; // 菌名称ID private ObservableCollection bacteriaCoordinatesSource; private ObservableCollection dgBacteriaCoordinates = new ObservableCollection(); public ExperimentRunChoiceBacteraModel expRunChoiceBactera = new ExperimentRunChoiceBacteraModel(); public event EventHandler stopEvent; public event EventHandler nextEvent; public HxSocketClient socketTcpListener = null; public bool isSimulator = false; public RunWnd launchView; // 运行窗体 public XmlNode methodNode; // 当前拍照的节点 public DataTable dtChoiceParams; // 当前成像参数 public bool cancelFlg = false; public bool isRemotingOper = false; // 是否是远程整合运行 private bool isDrawViewerInited = false; // 画图控件是否已初始化 private int countOfAutoanalysis = 0;//成像识别菌落数量 private int countOfManualchoice = 0;//人工挑选菌落数量 private int countOfManualdelete = 0;//人工删除菌落数量 private int countOfoating= 0;//涂布菌落总数 #endregion #region 构造函数 /// /// 构造函数 /// /// /// /// /// public ManualPickBacteria(string originalImageFilePath, string imagePath, string jsonPath, bool isSimulator) { try { InitializeComponent(); srcImageFile = originalImageFilePath; jsonFile = jsonPath; this.Owner = (Window)Shared.Main; } catch (Exception ex) { LoggerHelper.ErrorLog("ERROR:", ex); } } #endregion #region 初期表示处理 /// /// 初期表示处理 /// /// /// private void Window_Load(object sender, RoutedEventArgs e) { try { // 获取获取挑菌参数 GetBacteriasParamInfo(); // 获取拍照json文件里的数据 bacteriaCoordinatesSource = DataModule.getInstance().GetBacteriaCoordinateList(jsonFile); LoggerHelper.InfoLog(string.Format("[ManualPickBacteria]拍照挑菌个数:{0}", bacteriaCoordinatesSource.Count())); countOfAutoanalysis = bacteriaCoordinatesSource.Count(); dgPickData.ItemsSource = dgBacteriaCoordinates; drawViewer.BackgroundImage = BitmapFrame.Create(new Uri(srcImageFile), BitmapCreateOptions.None, BitmapCacheOption.OnLoad); } catch (Exception ex) { LoggerHelper.ErrorLog("ERROR:", ex); } } private void ElectroSysDisplay() { } #region 获取获取挑菌参数 /// /// 获取获取挑菌参数 /// private void GetBacteriasParamInfo() { string filePath = ConfigurationManager.AppSettings["choiceFilePath"]; if (!File.Exists(filePath)) { return; } // 获取挑菌参数 DataTable dtParam = ExcelAndCsvHelper.GetDataTableFromExcelFile(filePath, true); // 获取细菌信息 ObservableCollection listBacteria = DataModule.getInstance().GetBacterias(); Bacteria bacteria = listBacteria.Where(s => s.bacteria_name == this.textblockBacteriaName.Text).FirstOrDefault(); if (bacteria != null) { bacteriaTypeID = bacteria.bacteria_id; } #region 控件赋值 this.textblockTestID.Text = dtParam.Rows[0][2].ToString(); // 实验ID this.textblockDishBarcode.Text = dtParam.Rows[1][2].ToString(); // 皿码 this.textblockBacteriaName.Text = dtParam.Rows[2][2].ToString(); // 菌名称 this.textblockShape.Text = dtParam.Rows[3][2].ToString(); // 形状 this.textblockEdge.Text = dtParam.Rows[4][2].ToString(); // 边缘 this.textblockColor.Text = dtParam.Rows[5][2].ToString(); // 颜色 this.textblockMinDiameter.Text = dtParam.Rows[6][2].ToString(); // 最小直径 this.textblockMaxDiameter.Text = dtParam.Rows[7][2].ToString(); // 最大直径 this.textblockProximity.Text = dtParam.Rows[8][2].ToString(); // 邻近度 #endregion } #endregion #endregion #region 增加坐标 /// /// 增加坐标 /// /// /// private void drawCanvas_AddPointEvent(object sender, CustomRoutedEventArgs e) { try { PointData data = e.param as PointData; BacteriaCoordinateEx ex = new BacteriaCoordinateEx(); ex.bacteriacoordinate_id = data.id.ToString(); #region 暂时未用 //double x = data.point.X * 1.254; //double y = data.point.Y * 1.254; //Point point = new Point(x, y); //data.point = point; #endregion //ex.coordinate_pixel = Convert.ToInt32(Convert.ToDouble((data.point.X * 1.254).ToString("F2"))).ToString() + "," + Convert.ToInt32(Convert.ToDouble((data.point.Y * 1.254).ToString("F2"))).ToString(); ex.coordinate_pixel = Convert.ToInt32(Convert.ToDouble((data.point.X).ToString("F2"))).ToString() + "," + Convert.ToInt32(Convert.ToDouble((data.point.Y).ToString("F2"))).ToString(); ex.coordinate_machine = "0,0,0"; ex.diameter = data.diameter.ToString("F2"); ex.pixelPoint = data.point; //pixelPoint=====>machinePoint ex.machinePoint = new Point3D(0, 0, 0); ex.isManualPick = false; // 用户自己在画图上增加的,需要调用成像系统计算坐标 if (isDrawViewerInited) { Mouse.OverrideCursor = Cursors.Wait; List ret = ExecuteCalculate(ex, isSimulator); // 像素坐标转机械坐标 if (ret.Count == 2) { string dataSrc = ret[1]; string dataChg = dataSrc.Replace("#!HxSEP!#", ""); JObject job = JObject.Parse(dataChg); int iType = Convert.ToInt32(job["message_type"].ToString()); if (iType == 5) { JArray jArray = (JArray)job["data"]["result"]; ex.coordinate_machine = jArray[0]["x"].ToString() + "," + jArray[0]["y"].ToString() + "," + jArray[0]["z"].ToString(); } } Mouse.OverrideCursor = null; ex.isManualPick = true; LoggerRunHelper.InfoLog(string.Format("[ManualPickBacteria][drawCanvas_AddPointEvent]人工增加坐标: 像素坐标:{0}, 机械坐标:{1}", ex.coordinate_pixel, ex.coordinate_machine)); } else { ex.coordinate_machine = data.coordinate_machine; } dgBacteriaCoordinates.Add(ex); countOfManualchoice++; tbxCountOfSelected.Text= dgBacteriaCoordinates.Count.ToString(); } catch (Exception ex) { LoggerHelper.ErrorLog("ERROR:", ex); } } #region 像素坐标转成机械坐标 /// /// 像素坐标转成机械坐标 /// /// 像素坐标对象 /// /// 结果实体对象 private List ExecuteCalculate(BacteriaCoordinateEx bacteriaCoordinateEx, bool isSimulator = false) { // 像素坐标转成机械坐标 List strResult = socketTcpListener.SendMessage(GenerateCommand(bacteriaCoordinateEx), true); return strResult; } /// /// 像素坐标转换成机械坐标 /// /// /// private string GenerateCommand(BacteriaCoordinateEx bacteriaCoordinateEx) { string strCommand = string.Empty; try { if (bacteriaCoordinateEx != null) { string pixelGroup = bacteriaCoordinateEx.coordinate_pixel; string[] pixels = pixelGroup.Split(','); string pixelx = pixels[0]; string pixely = pixels[1]; string experimentid = "Unknown"; strCommand = "{" + "\"message_id\":\"" + Guid.NewGuid().ToString() + "\",\"message_type\":1" + ",\"method\":\"Calculate\"" + ",\"equipment_id\":\"ID2023\"" + ",\"workflow_id\":\"\"" + ",\"experiment_id\":\"" + experimentid + "\",\"parameters\":" + "{" + "\"data\":[{" + "\"x\":" + pixelx + ",\"y\":" + pixely + "}]" + "}" + ",\"process_info\":{}" + ",\"estimate_time\":5" + ",\"timeout\":60" + ",\"description\":\"NO DESC\"" + ",\"timestamp\":\"" + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + "\"}"; } } catch (Exception ex) { LoggerHelper.ErrorLog("ERROR:", ex); } return strCommand; } #endregion #endregion #region 删除坐标 /// /// 删除坐标 /// /// /// private void delete_Button_Click(object sender, RoutedEventArgs e) { try { Button btn = (Button)sender; if (btn != null) { string id = btn.Tag as string; BacteriaCoordinateEx bacteriaItem = dgBacteriaCoordinates.Where(s => s.bacteriacoordinate_id == id).FirstOrDefault(); // 删除菌落坐标 if (DeleteBacteriaItem(bacteriaItem)) { dgBacteriaCoordinates.Remove(bacteriaItem); tbxCountOfSelected.Text = dgBacteriaCoordinates.Count.ToString(); } } } catch (Exception ex) { LoggerHelper.ErrorLog("ERROR:", ex); } } /// /// 删除菌落坐标 /// /// /// private bool DeleteBacteriaItem(BacteriaCoordinateEx bacteriaItem) { if (bacteriaItem != null) { Visual dv = drawCanvas.GetVisual(Convert.ToInt32(bacteriaItem.bacteriacoordinate_id)); if (dv != null) { // 删除Visual drawCanvas.DeleteVisual(dv); // 删除DataGridItem countOfManualdelete++; LoggerRunHelper.InfoLog(string.Format("[ManualPickBacteria][DeleteBacteriaItem]: 删除坐标成功: 像素坐标:{0}, 机械坐标:{1}", bacteriaItem.coordinate_pixel, bacteriaItem.coordinate_machine)); return true; } else { LoggerRunHelper.ErrorLog(string.Format("[ManualPickBacteria][DeleteBacteriaItem]: 删除坐标失败: bacteriacoordinate_id:{0}", bacteriaItem.bacteriacoordinate_id)); return false; } } else { LoggerRunHelper.ErrorLog(string.Format("[ManualPickBacteria][DeleteBacteriaItem]: bacteriaItem = null, 删除失败!")); return false; } } #endregion #region 确认挑选按钮事件 /// /// 确认挑选按钮事件 /// /// /// private void btnConfirm_Click(object sender, RoutedEventArgs e) { try { // 进入到手工设置板位数据 string fileName = $"{Shared.Exp.ExperimentId}_{DateTime.Now.ToString("yyyyMMddTHHmmssms")}"; string imageFilePath = SaveBacteriaResultImage(fileName); // 手工挑选之后的图 string jsonFilePath = SaveJsonResult(fileName); // 手工挑选之后的json if(launchView!= null) { expRunChoiceBactera.CountAutoAnalysis = countOfAutoanalysis; expRunChoiceBactera.CountManualChoice = countOfManualchoice; expRunChoiceBactera.CountManualDelete = countOfManualdelete; expRunChoiceBactera.CountCoating = countOfoating; expRunChoiceBactera.SourceImagePath = srcImageFile; expRunChoiceBactera.UpdateImagePath = imageFilePath; expRunChoiceBactera.UpdateJsonPath = jsonFilePath; string filePath = ConfigurationManager.AppSettings["choiceFilePath"];// 挑菌下发参数.xls dtChoiceParams = ExcelAndCsvHelper.GetDataTableFromExcelFile(filePath, true); expRunChoiceBactera.BacteriaName = dtChoiceParams.Rows[2]["属性值"].ToString(); expRunChoiceBactera.BacteriaColor = dtChoiceParams.Rows[5]["属性值"].ToString(); expRunChoiceBactera.BacteriaEdge = dtChoiceParams.Rows[4]["属性值"].ToString(); expRunChoiceBactera.BacteriaShape = dtChoiceParams.Rows[3]["属性值"].ToString(); expRunChoiceBactera.BacteriaMinSize = Convert.ToDouble(dtChoiceParams.Rows[6]["属性值"].ToString()); expRunChoiceBactera.BacteriaMaxSize = Convert.ToDouble(dtChoiceParams.Rows[7]["属性值"].ToString()); expRunChoiceBactera.BacteraProx = Convert.ToDouble(dtChoiceParams.Rows[8]["属性值"].ToString()); ExperimentRunChoiceBacteraDB.Add(expRunChoiceBactera); } ConfirmNext confirmNext = new ConfirmNext(); if (isRemotingOper) // 远程整合调用中,发送挑菌结构给中控 { //if (launchView != null) //{ // //原图路径 // var folder = System.IO.Path.Combine(Environment.CurrentDirectory, "UploadFolder"); // string strSourcePic = imageSrcFile; // //手挑后的图路径 // string strChoicedPic = Path.GetFileName(imageFilePath); // //手挑后的数据文件 // string strChoicedData = Path.GetFileName(jsonFilePath); // string ip = HttpServer.GetLocalIP(); // string port = ConfigurationManager.AppSettings["socketURLPort"].ToString(); // string server = $"http://{ip}:{port}/UploadFolder/"; // string resultJson = "{\"json\":\"" + server + strChoicedData + "\"," + // "\"image\":\"" + server + strChoicedPic + "\"," + // "\"original\":\"" + strSourcePic + "\"" + // "}"; // LoggerHelper.InfoLog("【" + DateTime.Now.ToString("HH:mm:ss:fff") + "】>Xhandler: 【TakePhoto】remote progress:send data: " + JObject.Parse(resultJson).ToString()); // launchView.captureData = JObject.Parse(resultJson).ToString(); // this.Close(); //} return; } else { this.Visibility = Visibility.Hidden; confirmNext.Height = this.ActualHeight; confirmNext.Width = this.ActualWidth; confirmNext.manualPickBacteria = this; confirmNext.launchView = launchView; confirmNext.methodNode = methodNode; confirmNext.dtChoiceParams = dtChoiceParams; SolidColorBrush mybtn1_Brush = new SolidColorBrush(System.Windows.Media.Color.FromArgb(0, 0, 0, 0)); confirmNext.Background = (System.Windows.Media.Brush)mybtn1_Brush; confirmNext.dgBacteriaCoordinates = dgBacteriaCoordinates; confirmNext.ShowDialog(); } cancelFlg = confirmNext.cancelFlg; } catch (Exception ex) { LoggerHelper.ErrorLog("ERROR:", ex); } } #endregion #region 图片相关事件 #region 图片控件加载事件 /// /// 图片控件加载事件 /// /// /// private void drawViewer_Loaded(object sender, RoutedEventArgs e) { try { startZoom = drawViewer.Zoom; drawCanvas.ID = 1; Point point; LoggerHelper.DebugLog(string.Format("[drawViewer_Loaded]: start draw, bacteriaCnt = {0}", bacteriaCoordinatesSource.Count())); foreach (BacteriaCoordinateEx item in bacteriaCoordinatesSource) { string[] pixels = item.coordinate_pixel.Split(','); //point = new Point((Convert.ToDouble(pixels[0]) / 1.254), (Convert.ToDouble(pixels[1]) / 1.254)); point = new Point((Convert.ToDouble(pixels[0])), (Convert.ToDouble(pixels[1]))); drawCanvas.MouseLeftButtonDown(point); // 机械坐标 string coordinateMachine = string.Format("{0},{1},{2}", item.machinePoint.X, item.machinePoint.Y, item.machinePoint.Z); drawCanvas.MouseLeftButtonUp(point, coordinateMachine); } LoggerHelper.DebugLog(string.Format("[drawViewer_Loaded]: end draw")); // 自动挑菌时,自动点击确认按钮 string choicemode = dtChoiceParams.Rows[9]["属性值"].ToString(); if (choicemode.Equals("0")) // 0:成像系统自动挑选菌落 { btnConfirm_Click(null, null); } } catch (Exception ex) { LoggerHelper.ErrorLog("ERROR:", ex); } finally { // 画图控件已初始化 isDrawViewerInited = true; LoggerHelper.DebugLog(string.Format("[drawViewer_Loaded]: call finished")); } } #endregion #region 缩小按钮事件 /// /// 缩小按钮事件 /// /// /// private void btnZoomin_Click(object sender, RoutedEventArgs e) { try { double zoom = drawViewer.Zoom * 0.8; drawViewer.Zoom = zoom; } catch (Exception ex) { LoggerHelper.ErrorLog("ERROR:", ex); } } #endregion #region 放大按钮事件 /// /// 放大按钮事件 /// /// /// private void btnZoomout_Click(object sender, RoutedEventArgs e) { try { double zoom = drawViewer.Zoom * 1.2; drawViewer.Zoom = zoom; } catch (Exception ex) { LoggerHelper.ErrorLog("ERROR:", ex); } } #endregion #region 还原图像按钮事件 /// /// 还原图像按钮事件 /// /// /// private void btnFit_Click(object sender, RoutedEventArgs e) { try { drawViewer.Zoom = startZoom; } catch (Exception ex) { LoggerHelper.ErrorLog("ERROR:", ex); } } #endregion #endregion /// /// 保存挑菌图片 /// /// /// private string SaveBacteriaResultImage(string fileName) { string imageFilePath = string.Empty; // 保存成图片 var backgroundImage = this.drawViewer.BackgroundImage; var frame = this.drawCanvas.ToBitmapFrame(backgroundImage.PixelWidth, backgroundImage.PixelHeight, DpiHelper.GetDpiFromVisual(this.drawCanvas), backgroundImage); if (frame == null) return imageFilePath; var pickResultPath = ConfigurationManager.AppSettings["PickResultPath"]; if (!Directory.Exists(pickResultPath)) { Directory.CreateDirectory(pickResultPath); } imageFilePath = pickResultPath + fileName + ".jpg"; ImageHelper.Save(imageFilePath, frame); return imageFilePath; } /// /// 保存挑菌数据成json格式文件 /// /// /// private string SaveJsonResult(string fileName) { string jsonFilePath = string.Empty; string jsonData = File.ReadAllText(jsonFile); jsonData = jsonData.Replace("#!HxSEP!#", ""); JObject job = JObject.Parse(jsonData); job["count"] = dgBacteriaCoordinates.Count; JArray jArray = (JArray)job["germlist"]; jArray.Clear(); foreach (BacteriaCoordinateEx item in dgBacteriaCoordinates) { if (!item.canEdit) continue; JObject newObj = new JObject(); newObj.Add("index", item.bacteriacoordinate_id); newObj.Add("orgType", bacteriaTypeID); newObj.Add("diameterSize", item.diameter); newObj.Add("proximity", textblockProximity.Text); newObj.Add("shape", textblockShape.Text); newObj.Add("edge", textblockEdge.Text); newObj.Add("color", textblockColor.Text); newObj.Add("manualPick", item.isManualPick.ToString().ToLower()); JObject pixelObj = new JObject(); pixelObj.Add("x", item.pixelPoint.X); pixelObj.Add("y", item.pixelPoint.Y); newObj.Add("coordinatePixel", pixelObj); JObject coorObj = new JObject(); coorObj.Add("x", item.coordinate_machine.Split(',')[0]); coorObj.Add("y", item.coordinate_machine.Split(',')[1]); coorObj.Add("z", item.coordinate_machine.Split(',')[2]); newObj.Add("coordinate3D", coorObj); jArray.Add(newObj); } countOfoating = dgBacteriaCoordinates.Count; if (!isRemotingOper) { var pickResultPath = ConfigurationManager.AppSettings["PickResultPath"]; if (!Directory.Exists(pickResultPath)) { Directory.CreateDirectory(pickResultPath); } jsonFilePath = pickResultPath + fileName + ".json"; using (System.IO.StreamWriter file = new System.IO.StreamWriter(jsonFilePath)) { string data = job.ToString() + "#!HxSEP!#"; file.Write(data); } } else { var folder = System.IO.Path.Combine(Environment.CurrentDirectory, "UploadFolder"); if (!Directory.Exists(folder)) { Directory.CreateDirectory("UploadFolder"); } jsonFilePath = folder + "\\" + fileName + ".json"; using (System.IO.StreamWriter file = new System.IO.StreamWriter(jsonFilePath)) { string data = job.ToString();// + "#!HxSEP!#"; file.Write(data); } } return jsonFilePath; } #region Del /// /// 暂未使用 /// /// /// private void ConfirmNext_okEvent(object sender, EventArgs e) { try { //执行下一个命令 string strDateTime = DateTime.Now.ToString("yyyyMMddTHHmmssms"); SaveBacteriaResultImage(strDateTime); SaveJsonResult(strDateTime); Confirm_closeEvent(sender, EventArgs.Empty); nextEvent?.Invoke(this, EventArgs.Empty); CoatingSetting coatingSetting = new CoatingSetting(); coatingSetting.Height = this.ActualHeight; coatingSetting.Width = this.ActualWidth; coatingSetting.launchView = launchView; coatingSetting.methodNode = methodNode; coatingSetting.dtChoiceParams = dtChoiceParams; SolidColorBrush mybtn1_Brush = new SolidColorBrush(System.Windows.Media.Color.FromArgb(0, 0, 0, 0)); coatingSetting.Background = (System.Windows.Media.Brush)mybtn1_Brush; coatingSetting.ShowDialog(); this.Close(); } catch (Exception ex) { LoggerHelper.ErrorLog("ERROR:", ex); } } /// /// 关闭页面:控件隐藏了 /// /// /// private void btnClose_Click(object sender, RoutedEventArgs e) { if (EventResponseController.Instance.CanExecute() == false) return; ConfirmClose confirmClose = new ConfirmClose(); confirmClose.closeEvent += Confirm_closeEvent; confirmClose.stopEvent += ConfirmClose_stopEvent; confirmClose.skipEvent += ConfirmClose_skipEvent; Window wnd = Application.Current.MainWindow; Grid parent = Utilities.FindVisualChild(wnd); parent.Children.Add(confirmClose); } /// /// 关闭页面:控件隐藏了 /// /// /// private void ConfirmClose_skipEvent(object sender, EventArgs e) { string strDateTime = DateTime.Now.ToString("yyyyMMddTHHmmssms"); // 跳过此步,执行下一命令 SaveBacteriaResultImage(strDateTime); SaveJsonResult(strDateTime); Confirm_closeEvent(sender, EventArgs.Empty); nextEvent?.Invoke(this, EventArgs.Empty); } /// /// 取消继续 /// /// /// private void ConfirmClose_stopEvent(object sender, EventArgs e) { // 停止当前流程 Confirm_closeEvent(sender, EventArgs.Empty); stopEvent?.Invoke(this, EventArgs.Empty); } private void Confirm_closeEvent(object sender, EventArgs e) { Window wnd = Application.Current.MainWindow; Grid grid = Utilities.FindVisualChild(wnd); UIElement element = sender as UIElement; grid.Children.Remove(element); } #endregion #region 全部删除 private void btnClear_Click(object sender, RoutedEventArgs e) { PlsToolTipWin plsToolTipWin = new PlsToolTipWin("确定要全部删除吗?"); plsToolTipWin.ShowDialog(); if (plsToolTipWin.DialogResult != true) { return; } if (dgBacteriaCoordinates != null && dgBacteriaCoordinates.Count > 0) { foreach (BacteriaCoordinateEx bacteriaItem in dgBacteriaCoordinates) { // 删除菌落坐标 DeleteBacteriaItem(bacteriaItem); } dgBacteriaCoordinates.Clear(); tbxCountOfSelected.Text = dgBacteriaCoordinates.Count.ToString(); } } #endregion } }