using MainShell.EventArgsFolder; using MainShell.Log; using MainShell.Vision; using MwFramework.Device; using MwFramework.Device.Model; using Stylet; using System; using System.Collections.Generic; using System.Linq; using AppCameraType = MainShell.Common.CameraType; namespace MainShell.ToolBox.ViewModel { public class VisionDisplayTestState : PropertyChangedBase { private AppCameraType _selectedCameraType = AppCameraType.TopPositionCamera; public AppCameraType SelectedCameraType { get { return _selectedCameraType; } set { SetAndNotify(ref _selectedCameraType, value); } } private bool _clearShapesBeforeDisplay = true; public bool ClearShapesBeforeDisplay { get { return _clearShapesBeforeDisplay; } set { SetAndNotify(ref _clearShapesBeforeDisplay, value); } } private string _statusMessage = "请选择主界面相机区域后发送测试事件。"; public string StatusMessage { get { return _statusMessage; } set { SetAndNotify(ref _statusMessage, value); } } } public class VisionDisplayTestViewModel : PropertyChangedBase { private const int ImageWidth = 320; private const int ImageHeight = 240; private readonly IEventAggregator _eventAggregator; private readonly VisionDisplayTestState _state; private readonly AppCameraType[] _cameraTypes; public VisionDisplayTestState State { get { return _state; } } public IEnumerable CameraTypes { get { return _cameraTypes; } } public VisionDisplayTestViewModel(IEventAggregator eventAggregator) { _eventAggregator = eventAggregator ?? throw new ArgumentNullException(nameof(eventAggregator)); _state = new VisionDisplayTestState(); _cameraTypes = Enum.GetValues(typeof(AppCameraType)).Cast().ToArray(); } public void SendImageEvent() { try { CameraData cameraData = CreateTestCameraData(); DisplayImageEventArgs message = new DisplayImageEventArgs(State.SelectedCameraType, cameraData); _eventAggregator.Publish(message); State.StatusMessage = $"已发送图片事件到 {State.SelectedCameraType},请查看主界面相机区域。"; } catch (Exception ex) { State.StatusMessage = $"发送图片事件失败:{ex.Message}"; ($"VisionDisplayTestViewModel.SendImageEvent exception: {ex}").LogSysError(); } } public void SendDisplayEvent() { try { FindTemplateResult result = CreateTestTemplateResult(); DisplayFindTemplateResultEventArgs message = new DisplayFindTemplateResultEventArgs( State.SelectedCameraType, result, State.ClearShapesBeforeDisplay); _eventAggregator.Publish(message); State.StatusMessage = $"已发送结果显示事件到 {State.SelectedCameraType},请查看主界面图形叠加。"; } catch (Exception ex) { State.StatusMessage = $"发送结果显示事件失败:{ex.Message}"; ($"VisionDisplayTestViewModel.SendDisplayEvent exception: {ex}").LogSysError(); } } public void ClearDisplayEvent() { try { DisplayFindTemplateResultEventArgs message = new DisplayFindTemplateResultEventArgs( State.SelectedCameraType, null, true); _eventAggregator.Publish(message); State.StatusMessage = $"已清空 {State.SelectedCameraType} 的图形叠加。"; } catch (Exception ex) { State.StatusMessage = $"清空结果显示失败:{ex.Message}"; ($"VisionDisplayTestViewModel.ClearDisplayEvent exception: {ex}").LogSysError(); } } private static CameraData CreateTestCameraData() { byte[] buffer = new byte[ImageWidth * ImageHeight * 3]; for (int y = 0; y < ImageHeight; y++) { for (int x = 0; x < ImageWidth; x++) { int offset = ((y * ImageWidth) + x) * 3; buffer[offset] = (byte)((x * 255) / ImageWidth); buffer[offset + 1] = (byte)((y * 255) / ImageHeight); buffer[offset + 2] = 40; } } AddCrossMark(buffer, ImageWidth / 2, ImageHeight / 2, 36, 255, 255, 255); CameraData cameraData = new CameraData( buffer, (uint)ImageWidth, (uint)ImageHeight, CustomPixelFormat.Rgb8Packed, 0L, DateTime.Now, false); cameraData.Bit = 3; return cameraData; } private static void AddCrossMark(byte[] buffer, int centerX, int centerY, int halfLength, byte blue, byte green, byte red) { for (int offsetX = -halfLength; offsetX <= halfLength; offsetX++) { SetPixel(buffer, centerX + offsetX, centerY, blue, green, red); } for (int offsetY = -halfLength; offsetY <= halfLength; offsetY++) { SetPixel(buffer, centerX, centerY + offsetY, blue, green, red); } } private static void SetPixel(byte[] buffer, int x, int y, byte blue, byte green, byte red) { if (x < 0 || x >= ImageWidth || y < 0 || y >= ImageHeight) { return; } int offset = ((y * ImageWidth) + x) * 3; buffer[offset] = blue; buffer[offset + 1] = green; buffer[offset + 2] = red; } private static FindTemplateResult CreateTestTemplateResult() { FindTemplateResult result = new FindTemplateResult(); result.CenterX = 160d; result.CenterY = 120d; result.Score = 0.987d; result.Contour = new FindTemplateContourResult { StartX = 90d, StartY = 70d, EndX = 230d, EndY = 170d }; result.Circles.Add(new FindTemplateCircleResult { CenterX = 160d, CenterY = 120d, Radius = 24d }); result.Lines.Add(new FindTemplateLineResult { StartX = 80d, StartY = 40d, EndX = 260d, EndY = 200d }); result.Rectangles.Add(new FindTemplateRectangleResult { StartX = 110d, StartY = 85d, Width = 90d, Height = 48d, Angle = Math.PI / 9d }); return result; } } }