using PaintDotNet.Adjust; using PaintDotNet.Adjust.BaseImage; using PaintDotNet.Annotation; using PaintDotNet.Annotation.Command; using PaintDotNet.Annotation.DedicatedAnalysis; using PaintDotNet.Annotation.Enum; using PaintDotNet.Annotation.FieldView; using PaintDotNet.Annotation.ImageCollect; using PaintDotNet.Annotation.Label; using PaintDotNet.Annotation.Measure; using PaintDotNet.Annotation.Other; using PaintDotNet.Annotation.PhysicalPhaseAction; using PaintDotNet.Base.CommTool; using PaintDotNet.Base.Enum; using PaintDotNet.Base.Functionodel; using PaintDotNet.Base.SettingModel; using PaintDotNet.Base.SettingModel.LVMModel; using PaintDotNet.Base.XmlSaveModel; using PaintDotNet.DbOpreate.DbModel; using PaintDotNet.SystemLayer; using System; using System.Collections.Generic; using System.ComponentModel; using System.Drawing; using System.Drawing.Drawing2D; using System.Reflection; using System.Threading; using System.Windows.Forms; using static PaintDotNet.Base.SettingModel.LabelStyleModel; namespace PaintDotNet { /// /// 主面板 /// public class DocumentPreview : UserControl, ISurfaceBox, DocumentDirtyObserver { #region 控件 private IContainer components = null; /// /// 左侧刻度标尺 /// public RulerPro leftRuler; /// /// 中心画布 /// public PanelEx panel; /// /// 顶部刻度标尺 /// public RulerPro topRuler; /// /// 右键菜单 /// private ContextMenuStrip contextMenuStrip1; private ToolStripMenuItem toolStripMenuItem1; private ToolStripMenuItem toolStripMenuItem2; private ToolStripMenuItem toolStripMenuItem3; private ToolStripMenuItem toolStripMenuItem4; #endregion private bool raiseFirstInputAfterGotFocus = false; private bool hookedMouseEvents = false; public bool previewMeasure = false; /// /// 为了保证图片绘制在画布中心 /// 设置的偏移量 /// private int _offsetW = 0; private int _offsetH = 0; private int _offsetHalfW = 0; private int _offsetHalfH = 0; /// /// 相的集合 /// public List phaseModels = new List(); /// /// 满屏网格是否显示,默认不显示 /// private bool gridLineFullEnabled = false; /// /// 网格是否显示,默认不显示 /// private bool gridLineEnabled = false; /// /// 矩形网格是否显示,默认不显示 /// private bool gridRectangleEnabled = false; /// /// 圆形网格是否显示,默认不显示 /// private bool gridRoundEnabled = false; /// /// 十字线是否显示,默认不显示 /// private bool gridCrossCurveEnabled = false; /// /// 辅助线是否显示,默认不显示 /// private bool auxiliaryLineEnabled = false; /// /// 视图标尺是否显示,默认显示 /// private bool rulersEnabled = false; /// /// 当前的视场行为标记,合并或删除 /// private CombineMode combineMode = CombineMode.Union; /// /// 标记连续绘制 /// private bool continuousDrawingLabel = false; /// /// 测量连续绘制 /// private bool continuousDrawingMeasure = false; /// /// 二值提取\连续操作 /// private bool continuousBinaryAction = false; /// /// 实际大小标记 /// private bool actualsize = false; /// /// 合适大小标记 /// private bool suitableSize = false; /// /// 合适高度标记 /// private bool suitableHeight = false; /// /// 合适宽度标记 /// private bool suitableWidth = false; /// /// 锁定扩缩 /// private bool lockZoom = false; /// /// 定倍显示 /// private bool fixedMultiple = false; /// /// 合并视场 /// private bool mergeFieldOfView = false; /// /// 删除视场 /// private bool deleteFieldOfView = false; /// /// 图层及文档信息 /// private Document _document; /// /// 图像内存块及其属性 /// private Surface _compositionSurface; /// /// 【标注、测量】用于保存测量、标注等的历史记录,用于撤销 /// public UndoManager undoManager; /// /// 【标注、测量】list of draw objects /// private GraphicsList graphicsList; /// /// 【标注、测量、视场、其它】当前激活的工具 /// public DrawToolType activeTool; public int ViewWidth { set { topRuler.HighlightLength = value; } } public int ViewHeigth { set { leftRuler.HighlightLength = value; } } /// /// 工具的集合 /// public Type[] tools; /// /// 初始化标记 /// private bool initialized; /// /// AppWorkspace接口 /// private IAppWorkspaceForSurfaceBox appWorkspace; /// /// 目前用于修改视场,如果是鼠标保持按下的状态,比如按下不抬起状态, /// 按下拖动状态,则不响应修改视场界面的相应numericUpDown等控件的值变化事件, /// 以避免事件的冲突 /// public bool mouseStatus; /// /// 辅助线的横线和竖线 /// GraphicsPath path, path1; /// /// 窗体状态 /// private FormWindowState oldWindowState = FormWindowState.Minimized; /// /// 缩放比例 /// private ScaleFactor scaleFactor = new ScaleFactor(1, 1); /// /// 每像素多少微米 /// private double micronRatio; /// /// 是否允许像素跟踪 /// public bool pixelTrackingEnabled = true; /// /// 是否允许刷新公共的底部的放大缩小的进度条和值 /// public bool refueshZoomTrackValue = true; private int toolNumber = -1; public DrawAnalysisModel AnalysisStyleModel { get; set; } /// /// 如果是false,则是弹窗的DocumentWorkspaceWindow /// public bool rightDown = true; /// /// ctrl按下事件 /// public bool controlPress = false; /// /// 在toolPointer的工具下,是否绘制鼠标划选的矩形 /// public bool drawRectangle = false; /// /// 在toolPointer的工具下,鼠标划选的矩形 /// public Rectangle rectangle; #region 直方图操作数据缓存 /// /// 亮度 /// private double histogramBeta = -0.5; /// /// 对比度 /// private double histogramAlpha = 1.0; /// /// gamma值 /// private double histogramGamma = 1.0; /// /// 最佳算法的数值,范围0-499 /// private int histogramPercent = 200; /// /// 是否选中了log /// private bool histogramLogEnabled; /// /// 是否选中了skip /// private bool histogramSkipEnabled; public Bitmap BoxBitmap; #endregion #region 直方图操作数据缓存 /// /// 亮度 /// public double HistogramBeta { set { this.histogramBeta = value; } get { return this.histogramBeta; } } /// /// 对比度 /// public double HistogramAlpha { set { this.histogramAlpha = value; } get { return this.histogramAlpha; } } public double HistogramGamma { set { this.histogramGamma = value; } get { return this.histogramGamma; } } public int HistogramPercent { set { this.histogramPercent = value; } get { return this.histogramPercent; } } public bool HistogramLogEnabled { set { this.histogramLogEnabled = value; } get { return this.histogramLogEnabled; } } public bool HistogramSkipEnabled { set { this.histogramSkipEnabled = value; } get { return this.histogramSkipEnabled; } } #endregion public DocumentPreview() { UI.InitScaling(this); InitializeComponent(); this._document = null; this._compositionSurface = null; this.panel.ScaleFactor = this.scaleFactor; this.panel.Paint += new PaintEventHandler(this.panelPaint); this.panel.MouseMove += new MouseEventHandler(this.MouseEvent_Move); this.panel.MouseDown += new MouseEventHandler(this.MouseEvent_Down); this.panel.MouseUp += new MouseEventHandler(this.MouseEvent_Up); this.panel.MouseClick += new MouseEventHandler(this.MouseEvent_Click); this.panel.MouseDoubleClick += new MouseEventHandler(this.MouseEvent_DoubleClick); this.InitToolsAndManager(); this.initialized = true; } public Rectangle DrawRectangle { get { return this.rectangle; } set { this.rectangle = value; } } public bool DrawRectangleFlag { get { return this.drawRectangle; } set { this.drawRectangle = value; } } public IAppWorkspaceForSurfaceBox AppWorkspaceTop { set { this.appWorkspace = value; } get { return this.appWorkspace; } } public GraphicsList GraphicsList { get { return graphicsList; } set { graphicsList = value; if (this.GraphicsList != null) { this.AdjustRendering(); //this.graphicsList.AddObserver(this); } } } void AdjustRendering() { Size docSize; if (this.GraphicsList != null) { docSize = this.GraphicsList.GetSize(); //AutoScrollMinSize = docSize; } else { //AutoScrollMinSize = new Size(0, 0); } Invalidate(); } public Surface CompositionSurface { get { return this._compositionSurface; } set { if (value != null) { this._compositionSurface = value; this.Refresh(); } } } public void ResetBoxBitmap() { this.BoxBitmap = this.CompositionSurface.CreateAliasedBitmap(); } public bool GridLineEnabled { get { return this.gridLineEnabled; } set { this.gridLineEnabled = value; } } public bool GridLineFullEnabled { get { return this.gridLineFullEnabled; } set { this.gridLineFullEnabled = value; } } public bool GridRectangleEnabled { get { return this.gridRectangleEnabled; } set { this.gridRectangleEnabled = value; } } public bool GridRoundEnabled { get { return this.gridRoundEnabled; } set { this.gridRoundEnabled = value; } } public bool GridCrossCurveEnabled { get { return this.gridCrossCurveEnabled; } set { this.gridCrossCurveEnabled = value; } } public double MicronRatio { get { return this.micronRatio; } set { this.micronRatio = value; } } public bool AuxiliaryLineEnabled { get { return auxiliaryLineEnabled; } set { this.auxiliaryLineEnabled = value; } } public bool ContinuousDrawingLabel { get { return continuousDrawingLabel; } set { this.continuousDrawingLabel = value; } } public bool ContinuousDrawingMeasure { get { return continuousDrawingMeasure; } set { this.continuousDrawingMeasure = value; } } public bool ContinuousBinaryAction { get { return continuousBinaryAction; } set { this.continuousBinaryAction = value; } } public bool ActualSize { get { return actualsize; } set { this.actualsize = value; } } public bool SuitableSize { get { return suitableSize; } set { this.suitableSize = value; } } public bool SuitableWidth { get { return suitableWidth; } set { this.suitableWidth = value; } } public bool SuitableHeight { get { return suitableHeight; } set { this.suitableHeight = value; } } public bool LockZoom { get { return lockZoom; } set { this.lockZoom = value; } } public bool FixedMultiple { get { return fixedMultiple; } set { this.fixedMultiple = value; } } public bool MergeFieldOfView { get { return mergeFieldOfView; } set { this.mergeFieldOfView = value; } } public bool DeleteFieldOfView { get { return deleteFieldOfView; } set { this.deleteFieldOfView = value; } } public bool RulersEnabled { get { return rulersEnabled; } set { //if (this.rulersEnabled != value) { this.rulersEnabled = value; if (this.topRuler != null) { this.topRuler.Enabled = value; this.topRuler.Visible = value; } if (this.leftRuler != null) { this.leftRuler.Enabled = value; this.leftRuler.Visible = value; } this.OnResize(EventArgs.Empty); OnRulersEnabledChanged(); } } } public CombineMode CombineMode { get { return this.combineMode; } set { this.combineMode = value; } } /// /// 初始化工具 /// private void InitToolsAndManager() { // 设置默认工具 activeTool = DrawToolType.Pointer; // 创建graphic list // 一是用于存储,二是用于调整层级 GraphicsList = new GraphicsList(this); // 创建管理器,用于前进后退 undoManager = new UndoManager(GraphicsList); // init Tools //tools = new Tool[(int)DrawToolType.NumberOfDrawTools]; tools = new Type[(int)DrawToolType.NumberOfDrawTools]; tools[(int)DrawToolType.Pointer] = typeof(ToolPointer); // //标注 // tools[(int)DrawToolType.DrawRectangle] = typeof(ToolRectangle); tools[(int)DrawToolType.DrawEllipse] = typeof(ToolEllipse); tools[(int)DrawToolType.DrawLine] = typeof(ToolLine); tools[(int)DrawToolType.DrawPolygon] = typeof(ToolPolygon); tools[(int)DrawToolType.DrawPolygonLine] = typeof(ToolPolygonLine); tools[(int)DrawToolType.DrawPencil] = typeof(ToolPencil); tools[(int)DrawToolType.DrawClosedCurve] = typeof(ToolClosedCurve); tools[(int)DrawToolType.DrawCurve] = typeof(ToolCurve); tools[(int)DrawToolType.DrawCircle] = typeof(ToolCircle); tools[(int)DrawToolType.DrawOneArrowLine] = typeof(ToolOneArrowLine); tools[(int)DrawToolType.DrawTwoArrowLine] = typeof(ToolTwoArrowLine); tools[(int)DrawToolType.DrawLineSegment] = typeof(ToolLineSegment); tools[(int)DrawToolType.DrawRoundRectangle] = typeof(ToolRoundRectangle); tools[(int)DrawToolType.DrawTextString] = typeof(ToolTextString); tools[(int)DrawToolType.DrawDateMark] = typeof(ToolDateMark); tools[(int)DrawToolType.DrawTimeMark] = typeof(ToolTimeMark); tools[(int)DrawToolType.DrawNumberMark] = typeof(ToolNumberMark); tools[(int)DrawToolType.DrawGainNumber] = typeof(ToolGainNumber); tools[(int)DrawToolType.DrawWorkType] = typeof(ToolWorkType); tools[(int)DrawToolType.DrawPointMark] = typeof(ToolPointMark); tools[(int)DrawToolType.DrawWaterMark] = typeof(ToolWaterMark); //分析绘图 tools[(int)DrawToolType.DrawCircleA] = typeof(ToolCircleA); tools[(int)DrawToolType.DrawMulLineA] = typeof(ToolDrawMulLineA); // //测量 // tools[(int)DrawToolType.MeasureLine] = typeof(ToolMeasureLine); tools[(int)DrawToolType.MeasureDistanceLine] = typeof(ToolMeasureDistanceLine); tools[(int)DrawToolType.MeasureLength] = typeof(ToolMeasureLength); tools[(int)DrawToolType.MeasureTraceCurve] = typeof(ToolMeasureTraceCurve); tools[(int)DrawToolType.MeasureHLine] = typeof(ToolMeasureHLine); tools[(int)DrawToolType.MeasureVLine] = typeof(ToolMeasureVLine); tools[(int)DrawToolType.MeasureCircle] = typeof(ToolMeasureCircle); tools[(int)DrawToolType.MeasureInnerCircle] = typeof(ToolMeasureInnerCircle); tools[(int)DrawToolType.MeasureOuterCircle] = typeof(ToolMeasureOuterCircle); tools[(int)DrawToolType.MeasureDiameterCircle] = typeof(ToolMeasureDiameterCircle); tools[(int)DrawToolType.MeasurePointEdgeSize] = typeof(ToolMeasurePointEdgeSize); tools[(int)DrawToolType.MeasurePointCenterSize] = typeof(ToolMeasurePointCenterSize); tools[(int)DrawToolType.MeasureBrokenLine] = typeof(ToolMeasureBrokenLine); tools[(int)DrawToolType.MeasureCurveLine] = typeof(ToolMeasureCurveLine); tools[(int)DrawToolType.MeasureThreePointAngle] = typeof(ToolMeasureThreePointAngle); tools[(int)DrawToolType.MeasureFourPointAngle] = typeof(ToolMeasureFourPointAngle); tools[(int)DrawToolType.MeasureThreePointArc] = typeof(ToolMeasureThreePointArc); tools[(int)DrawToolType.MeasurePLine] = typeof(ToolMeasurePLine); tools[(int)DrawToolType.MeasureMulPLine] = typeof(ToolMeasureMulPLine); tools[(int)DrawToolType.MeasureHMulPLine] = typeof(ToolMeasureHMulPLine); tools[(int)DrawToolType.MeasureVMulPLine] = typeof(ToolMeasureVMulPLine); tools[(int)DrawToolType.MeasureParallelLine] = typeof(ToolMeasureParallelLine); tools[(int)DrawToolType.MeasureMulParallelLine] = typeof(ToolMeasureMulParallelLine); tools[(int)DrawToolType.MeasureVMulParallelLine] = typeof(ToolMeasureVMulParallelLine); tools[(int)DrawToolType.MeasureHMulParallelLine] = typeof(ToolMeasureHMulParallelLine); tools[(int)DrawToolType.MeasureClosedCurve] = typeof(ToolMeasureClosedCurve); tools[(int)DrawToolType.MeasurePolygon] = typeof(ToolMeasurePolygon); tools[(int)DrawToolType.MeasureRectangle] = typeof(ToolMeasureRectangle); tools[(int)DrawToolType.MeasureRandRectangle] = typeof(ToolMeasureRandRectangle); tools[(int)DrawToolType.MeasureSquare] = typeof(ToolMeasureSquare); tools[(int)DrawToolType.MeasureTracePolygon] = typeof(ToolMeasureTracePolygon); tools[(int)DrawToolType.MeasureMulLine] = typeof(ToolMeasureMulLine); tools[(int)DrawToolType.MeasureMulSegment] = typeof(ToolMeasureMulSegment); tools[(int)DrawToolType.MeasureMulHVLine] = typeof(ToolMeasureMulHVLine); tools[(int)DrawToolType.MeasureMulVLine] = typeof(ToolMeasureMulVLine); tools[(int)DrawToolType.MeasureRandSquare] = typeof(ToolMeasureRandSquare); tools[(int)DrawToolType.MeasurePointHLine] = typeof(ToolMeasurePointHLine); tools[(int)DrawToolType.MeasurePointArcSize] = typeof(ToolMeasurePointArcSize); tools[(int)DrawToolType.MeasureCenterCenterSize] = typeof(ToolMeasureCenterCenterSize); tools[(int)DrawToolType.MeasureTwoLineVLDistance] = typeof(ToolMeasureTwoLineVLDistance); // //视场 // tools[(int)DrawToolType.ViewOval] = typeof(ToolViewOval); tools[(int)DrawToolType.ViewCircle] = typeof(ToolViewCircle); tools[(int)DrawToolType.ViewRectangle] = typeof(ToolViewRectangle); tools[(int)DrawToolType.ViewRectangleEx] = typeof(ToolViewRectangleEx); tools[(int)DrawToolType.ViewTriangle] = typeof(ToolViewTriangle); tools[(int)DrawToolType.ViewTriangleEx] = typeof(ToolViewTriangleEx); tools[(int)DrawToolType.ViewSquare] = typeof(ToolViewSquare); tools[(int)DrawToolType.ViewPolygon] = typeof(ToolViewPolygon); #region 对象处理 //单个提取 tools[(int)DrawToolType.BinaryExtract] = typeof(ToolBinaryExtract); //选择 tools[(int)DrawToolType.BinaryChoise] = typeof(ToolBinaryChoise); tools[(int)DrawToolType.BinaryChoiseRectangle] = typeof(ToolBinaryChoiseRectangle); tools[(int)DrawToolType.BinaryChoiseOval] = typeof(ToolBinaryChoiseOval); tools[(int)DrawToolType.BinaryChoisePolygon] = typeof(ToolBinaryChoisePolygon); //添加 tools[(int)DrawToolType.BinaryAddOval] = typeof(ToolBinaryAddOval); tools[(int)DrawToolType.BinaryAddRectangle] = typeof(ToolBinaryAddRectangle); tools[(int)DrawToolType.BinaryAddPolygon] = typeof(ToolBinaryAddPolygon); tools[(int)DrawToolType.BinaryAddTrack] = typeof(ToolBinaryAddTrack); //删除 tools[(int)DrawToolType.BinaryDelete] = typeof(ToolBinaryDelete); tools[(int)DrawToolType.BinaryDeleteRectangle] = typeof(ToolBinaryDeleteRectangle); tools[(int)DrawToolType.BinaryDeletePolygon] = typeof(ToolBinaryDeletePolygon); tools[(int)DrawToolType.BinaryDeleteOval] = typeof(ToolBinaryDeleteOval); //连接 tools[(int)DrawToolType.BinaryConnectionLine] = typeof(ToolBinaryConnectionLine); tools[(int)DrawToolType.BinaryConnectionPolygonLine] = typeof(ToolBinaryConnectionPolygonLine); tools[(int)DrawToolType.BinaryConnectionOval] = typeof(ToolBinaryConnectionOval); //分割 tools[(int)DrawToolType.BinarySplitLine] = typeof(ToolBinarySplitLine); tools[(int)DrawToolType.BinarySplitPolyline] = typeof(ToolBinarySplitPolyLine); tools[(int)DrawToolType.BinarySplitOval] = typeof(ToolBinarySplitOval); #endregion #region 专用分析 // 夹杂物 tools[(int)DrawToolType.InclusionNoEffect] = typeof(ToolInclusionNoEffect); tools[(int)DrawToolType.InclusionSelect] = typeof(ToolInclusionSelect); tools[(int)DrawToolType.InclusionPolygon] = typeof(ToolInclusionPolygon); tools[(int)DrawToolType.InclusionDrawRecognitionArea] = typeof(ToolInclusionDrawRecognitionArea); tools[(int)DrawToolType.InclusionSelectRecognitionArea] = typeof(ToolInclusionSelectRecognitionArea); #endregion #region 物相提取 //多边形 tools[(int)DrawToolType.PPhasePolygon] = typeof(ToolPPhasePolygon); //矩形 tools[(int)DrawToolType.PPhaseRectangle] = typeof(ToolPPhaseRectangle); //椭圆 tools[(int)DrawToolType.PPhaseOval] = typeof(ToolPPhaseOval); #endregion //其它 //手型工具 tools[(int)DrawToolType.MoveMode] = typeof(PanTool); //图片裁剪 tools[(int)DrawToolType.ImageCut] = typeof(ImageCutTool); //自动标尺 tools[(int)DrawToolType.DrawAutoRuler] = typeof(ToolAutoRuler); //预存标尺 tools[(int)DrawToolType.DrawPrestoredRuler] = typeof(ToolPrestoredRuler); //手动标尺 tools[(int)DrawToolType.DrawHandModeRuler] = typeof(ToolHandModeRuler); //光密度直线绘制 tools[(int)DrawToolType.OpticalDensityLine] = typeof(ToolOpticalDensityLine); //划痕处理 tools[(int)DrawToolType.DrawScratchTreatmentLine] = typeof(ToolScratchTreatmentLine); //污迹处理-矩形 tools[(int)DrawToolType.DrawSmudgeRectangle] = typeof(ToolSmudgeRectangle); //污迹处理-多边形 tools[(int)DrawToolType.DrawSmudgePolygon] = typeof(ToolSmudgePolygon); //污迹处理-圆形 tools[(int)DrawToolType.DrawSmudgeCircle] = typeof(ToolSmudgeCircle); //污迹处理-椭圆 tools[(int)DrawToolType.DrawSmudgeEllipse] = typeof(ToolSmudgeEllipse); //吸管工具 tools[(int)DrawToolType.ColorPicker] = typeof(ColorPickerTool); //null tools[(int)DrawToolType.NullTool] = typeof(ToolNull); // 图像拼接-矩形 tools[(int)DrawToolType.DrawStitchingRectangle] = typeof(ToolStitchingRectangle); // 图像拼接-圆形 tools[(int)DrawToolType.DrawStitchingCircle] = typeof(ToolStitchingCircle); // 图像拼接-多边形 tools[(int)DrawToolType.DrawStitchingPolygon] = typeof(ToolStitchingPolygon); // 工艺图对照点矩形 tools[(int)DrawToolType.DrawArtworkRectangle] = typeof(ToolArtworkRectangle); // 位置列表十字线 tools[(int)DrawToolType.DrawLocationCross] = typeof(ToolLocationCross); } public MeasurementUnit Units { get { return this.leftRuler.MeasurementUnit; } set { OnUnitsChanging(); this.leftRuler.MeasurementUnit = value; this.topRuler.MeasurementUnit = value; DocumentMetaDataChangedHandler(this, EventArgs.Empty); OnUnitsChanged(); } } protected virtual void OnUnitsChanging() { } protected virtual void OnUnitsChanged() { } /// /// 获取系统当前选中单位及每单位像素值 /// /// 3位字符串数组, /// 0:系统选中单位枚举字符串 /// 1:系统选中单位名称字符串 /// 2:系统选中单位符号字符串 /// 3:系统选中单位每单位像素长度 /// 4:系统选中单位每单位物理长度 /// protected virtual string[] startUpRules(Dictionary rules) { return new string[] { }; } [Browsable(false)] public override bool Focused { get { return base.Focused || panel.Focused || leftRuler.Focused || topRuler.Focused; } } public new BorderStyle BorderStyle { get { return this.panel.BorderStyle; } set { this.panel.BorderStyle = value; } } private void Renderers_Invalidated(object sender, InvalidateEventArgs e) { Rectangle rect = SurfaceToClient(e.InvalidRect); rect.Inflate(1, 1); Invalidate(rect); } /// /// 计算像素跟踪的点 /// /// /// public Point CalcPixelPoint(Point point) { Rectangle rc = this.panel.ClientRectangle; int width = (int)(this._compositionSurface.Width * this.scaleFactor.Ratio); int height = (int)(this._compositionSurface.Height * this.scaleFactor.Ratio); int x = (rc.Width < width) ? this.panel.AutoScrollPosition.X + _offsetHalfW : (rc.Width - width) / 2; int y = (rc.Height < height) ? this.panel.AutoScrollPosition.Y + _offsetHalfH : (rc.Height - height) / 2; point.X -= x; point.Y -= y; return this.ScaleFactor.UnscalePoint(point); } protected override void OnLoad(EventArgs e) { base.OnLoad(e); this.panel.Select(); } public void HookMouseEvents() { if (!this.hookedMouseEvents) { this.hookedMouseEvents = true; foreach (Control c in Controls) { HookMouseEvents(c); } } } public void PerformMouseWheel(Control sender, MouseEventArgs e) { HandleMouseWheel(sender, e); } protected override void OnMouseWheel(MouseEventArgs e) { HandleMouseWheel(this, e); base.OnMouseWheel(e); } /// /// 鼠标滚轮事件 /// /// /// protected virtual void HandleMouseWheel(Control sender, MouseEventArgs e) { double docDelta = (double)e.Delta / this.ScaleFactor.Ratio; double oldX = this.DocumentScrollPositionF.X; double oldY = this.DocumentScrollPositionF.Y; double newX; double newY; if (Control.ModifierKeys == Keys.Control) { double mouseDelta = (double)e.Delta / 120.0f; Rectangle visibleDocBoundsStart = this.VisibleDocumentBounds; Rectangle rc = this.PanelClientRectangle; int width = this.SurfaceScrollableWidth; int height = this.SurfaceScrollableHeight; if ((rc.Width < width||rc.Height < height)&& e.Delta > 0) { return; } const double factor = 1.12; double mouseFactor = Math.Pow(factor, Math.Abs(mouseDelta)); if (e.Delta > 0) { this.ZoomIn(mouseFactor); } else if (e.Delta < 0) { this.ZoomOut(mouseFactor); } int width2 = this.SurfaceScrollableWidth; int height2 = this.SurfaceScrollableHeight; if ((rc.Width < width2 || rc.Height < height2) && (rc.Width < width || rc.Height < height)) { } else if (rc.Width < width2 || rc.Height < height2) { this.PanelScrollPosition = new System.Drawing.Point((int)(width2 - rc.Width) / 2 + 0, (int)(height2 - rc.Height) / 2 + 0); } else { this.PanelScrollPosition = new System.Drawing.Point((int)(width2 - rc.Width) / 2 + 0, (int)(height2 - rc.Height) / 2 + 0); } Rectangle visibleDocBoundsEnd = this.VisibleDocumentBounds; //解决缩放后拼图区域显示不正确的问题 RulerOffsetX = RulerOffsetX; RulerOffsetY = RulerOffsetY; if (visibleDocBoundsEnd != visibleDocBoundsStart) { // Make sure the screen updates, otherwise it can get a little funky looking this.Update(); } } if (Control.ModifierKeys == Keys.Shift) { this.panel.Response = false; // scroll horizontally newX = this.DocumentScrollPositionF.X - docDelta; newY = this.DocumentScrollPositionF.Y; } else if (Control.ModifierKeys == Keys.None) { this.panel.Response = true; // scroll vertically newX = this.DocumentScrollPositionF.X; newY = this.DocumentScrollPositionF.Y - docDelta; } else { this.panel.Response = false; // no change newX = this.DocumentScrollPositionF.X; newY = this.DocumentScrollPositionF.Y; } if (newX != oldX || newY != oldY) { this.DocumentScrollPositionF = new PointF((float)newX, (float)newY); UpdateRulerOffsets(); } } /// /// Get or set upper left of scroll location in document coordinates. /// [Browsable(false)] public PointF DocumentScrollPositionF { get { if (this.panel == null) { return PointF.Empty; } else { return this.panel.ScrollPosition; //return VisibleDocumentRectangleF.Location; } } set { if (panel == null) { return; } else { this.panel.ScrollPosition = new Point((int)value.X, (int)value.Y); } /** PointF sbClientF = this.panel.SurfaceToClient(value); Point sbClient = Point.Round(sbClientF); if (this.panel.AutoScrollPosition != new Point(-sbClient.X, -sbClient.Y)) { this.panel.AutoScrollPosition = sbClient; UpdateRulerOffsets(); this.topRuler.Invalidate(); this.leftRuler.Invalidate(); }**/ } } public Point PanelScrollPosition { get { return this.panel.ScrollPosition; } set { this.panel.ScrollPosition = value; } } [Browsable(false)] public PointF DocumentCenterPointF { get { RectangleF vsb = VisibleDocumentRectangleF; PointF centerPt = new PointF((vsb.Left + vsb.Right) / 2, (vsb.Top + vsb.Bottom) / 2); return centerPt; } set { RectangleF vsb = VisibleDocumentRectangleF; PointF newCornerPt = new PointF(value.X - (vsb.Width / 2), value.Y - (vsb.Height / 2)); this.DocumentScrollPositionF = newCornerPt; } } /// /// Clean up any resources being used. /// protected override void Dispose(bool disposing) { if (disposing) { if (this.components != null) { this.components.Dispose(); this.components = null; } if (this._compositionSurface != null) { this._compositionSurface.Dispose(); this._compositionSurface = null; } } base.Dispose(disposing); } /// /// 缩放比例改变事件 /// public event EventHandler ScaleFactorChanged; protected virtual void OnScaleFactorChanged() { if (ScaleFactorChanged != null) { ScaleFactorChanged(this, EventArgs.Empty); } } /// /// 像素网格是否绘制的bool标记改变事件 /// public event EventHandler DrawGridChanged; protected virtual void OnDrawGridChanged() { if (DrawGridChanged != null) { DrawGridChanged(this, EventArgs.Empty); } } #region /// /// 合适大小 /// public void ZoomToWindow() { if (this._document != null) { Rectangle max = ClientRectangleMax; ScaleFactor zoom = ScaleFactor.Min(max.Width - 10, _document.Width, max.Height - 10, _document.Height, ScaleFactor.MinValue); ScaleFactor min = ScaleFactor.Min(zoom, ScaleFactor.OneToOne); this.ScaleFactor = min; } } /// /// 合适宽度 /// public void ZoomToWidth() { if (this._document != null) { Rectangle max = ClientRectangleMax; ScaleFactor zoom = ScaleFactor.UseIfValid(max.Width - 40, _document.Width, ScaleFactor.MinValue); ScaleFactor min = ScaleFactor.Min(zoom, ScaleFactor.OneToOne); this.ScaleFactor = min; } } /// /// 合适高度 /// public void ZoomToHeight() { if (this._document != null) { Rectangle max = ClientRectangleMax; ScaleFactor zoom = ScaleFactor.UseIfValid(max.Height - 20, _document.Height, ScaleFactor.MinValue); ScaleFactor min = ScaleFactor.Min(zoom, ScaleFactor.OneToOne); this.ScaleFactor = min; } } private double GetZoomInFactorEpsilon() { double ratio = this.ScaleFactor.Ratio; return (ratio + 0.01) / ratio; /** // Increase ratio by 1 percentage point double currentRatio = this.ScaleFactor.Ratio; double factor1 = (currentRatio + 0.01) / currentRatio; // Increase ratio so that we increase our view by 1 pixel double ratioW = (double)(this.panel.Width + 1) / (double)this.compositionSurface.Width; double ratioH = (double)(this.panel.Height + 1) / (double)this.compositionSurface.Height; double ratio = Math.Max(ratioW, ratioH); double factor2 = ratio / currentRatio; double factor = Math.Max(factor1, factor2); return factor; **/ } private double GetZoomOutFactorEpsilon() { double ratio = this.ScaleFactor.Ratio; return (ratio - 0.01) / ratio; } public virtual void ZoomIn(double factor) { Do.TryBool(() => ZoomInImpl(factor)); } private void ZoomInImpl(double factor) { PointF centerPt = this.DocumentCenterPointF; ScaleFactor oldSF = this.ScaleFactor; ScaleFactor newSF = this.ScaleFactor; int countdown = 3; // At a minimum we want to increase the size of visible document by 1 pixel // Figure out what the ratio of ourSize : ourSize+1 is, and start out with that double zoomInEps = GetZoomInFactorEpsilon(); double desiredFactor = Math.Max(factor, zoomInEps); double newFactor = desiredFactor; // Keep setting the ScaleFactor until it actually 'sticks' // Important for certain image sizes where not all zoom levels create distinct // screen sizes do { newSF = ScaleFactor.FromDouble(newSF.Ratio * newFactor); this.ScaleFactor = newSF; --countdown; newFactor *= 1.10; } while (this.ScaleFactor == oldSF && countdown > 0); this.DocumentCenterPointF = centerPt; } public virtual void ZoomIn() { Do.TryBool(ZoomInImpl); } private void ZoomInImpl() { PointF centerPt = this.DocumentCenterPointF; ScaleFactor oldSF = this.ScaleFactor; ScaleFactor newSF = this.ScaleFactor; int countdown = ScaleFactor.PresetValues.Length; // Keep setting the ScaleFactor until it actually 'sticks' // Important for certain image sizes where not all zoom levels create distinct // screen sizes do { newSF = newSF.GetNextLarger(); this.ScaleFactor = newSF; --countdown; } while (this.ScaleFactor == oldSF && countdown > 0); this.DocumentCenterPointF = centerPt; } public virtual void ZoomOut(double factor) { Do.TryBool(() => ZoomOutImpl(factor)); } private void ZoomOutImpl(double factor) { PointF centerPt = this.DocumentCenterPointF; ScaleFactor oldSF = this.ScaleFactor; ScaleFactor newSF = this.ScaleFactor; int countdown = 3; // At a minimum we want to decrease the size of visible document by 1 pixel (without dividing by zero of course) // Figure out what the ratio of ourSize : ourSize-1 is, and start out with that double zoomOutEps = GetZoomOutFactorEpsilon(); double factorRecip = 1.0 / factor; double desiredFactor = Math.Min(factorRecip, zoomOutEps); double newFactor = desiredFactor; // Keep setting the ScaleFactor until it actually 'sticks' // Important for certain image sizes where not all zoom levels create distinct // screen sizes do { newSF = ScaleFactor.FromDouble(newSF.Ratio * newFactor); this.ScaleFactor = newSF; --countdown; newFactor *= 0.9; } while (this.ScaleFactor == oldSF && countdown > 0); this.DocumentCenterPointF = centerPt; } public virtual void ZoomOut() { Do.TryBool(ZoomOutImpl); } private void ZoomOutImpl() { PointF centerPt = this.DocumentCenterPointF; ScaleFactor oldSF = this.ScaleFactor; ScaleFactor newSF = this.ScaleFactor; int countdown = ScaleFactor.PresetValues.Length; do { newSF = newSF.GetNextSmaller(); this.ScaleFactor = newSF; --countdown; } while (this.ScaleFactor == oldSF && countdown > 0); this.DocumentCenterPointF = centerPt; } [Browsable(false)] public ScaleFactor ScaleFactor { get { return this.scaleFactor; } set { UI.SuspendControlPainting(this); ScaleFactor newValue = ScaleFactor.Min(value, ScaleFactor.MaxValue); if (newValue == this.scaleFactor && this.scaleFactor == ScaleFactor.OneToOne) { // this space intentionally left blank } else { RectangleF visibleRect = this.VisibleDocumentRectangleF; ScaleFactor oldSF = scaleFactor; scaleFactor = newValue; // This value is used later below to re-center the document on screen PointF centerPt = new PointF(visibleRect.X + visibleRect.Width / 2, visibleRect.Y + visibleRect.Height / 2); if (_compositionSurface != null) { Rectangle rc = this.panel.ClientRectangle; int width = (int)(this._compositionSurface.Width * this.scaleFactor.Ratio); int height = (int)(this._compositionSurface.Height * this.scaleFactor.Ratio); if (rc.Width < width || rc.Height < height) { this.panel.AutoScrollMinSize = new Size((int)(this._compositionSurface.Width * scaleFactor.Ratio) + _offsetW, (int)(this._compositionSurface.Height * scaleFactor.Ratio) + _offsetH); } else { this.panel.AutoScrollMinSize = new Size((int)(this._compositionSurface.Width * scaleFactor.Ratio), (int)(this._compositionSurface.Height * scaleFactor.Ratio)); } this.panel.ScaleFactor = this.scaleFactor; if (leftRuler != null) { this.leftRuler.ScaleFactor = scaleFactor; } if (topRuler != null) { this.topRuler.ScaleFactor = scaleFactor; } } // re center ourself RectangleF visibleRect2 = this.VisibleDocumentRectangleF; RecenterView(centerPt); } this.OnResize(EventArgs.Empty); this.OnScaleFactorChanged(); if (this.appWorkspace != null && refueshZoomTrackValue && this.rightDown) { this.appWorkspace.SetZoonTrackValue(newValue); } /* //设置底部缩放比列的百分比tracker的值 this.panelBottom.trackBar.Maximum = (int)(ScaleFactor.MaxValue.Ratio * 100); if (newValue != null) { this.PanelBottom.trackBar.ValueChanged -= this.PanelBottom_trackBar_ValueChanged; this.PanelBottom.trackBar.Value = (int)(newValue.Ratio * 100); this.PanelBottom.trackBar.ValueChanged += new EventHandler(this.PanelBottom_trackBar_ValueChanged); } //设置底部缩放比例的百分比textbox的值 this.PanelBottom.textBox.Text = newValue.ToString(); */ UI.ResumeControlPainting(this); Invalidate(true); } } #endregion /// /// Returns a rectangle for the bounding rectangle of what is currently visible on screen, /// in document coordinates. /// [Browsable(false)] public RectangleF VisibleDocumentRectangleF { get { Rectangle panelRect = this.panel.RectangleToScreen(this.panel.ClientRectangle); // screen coords coords Rectangle docScreenRect = panelRect; // screen coords Rectangle docClientRect = RectangleToClient(docScreenRect); RectangleF docDocRectF = ClientToDocument(docClientRect); return docDocRectF; } } public Rectangle PanelClientRectangle { get { return panel.ClientRectangle; } } public int SurfaceScrollableWidth { get { return (int)(this._compositionSurface.Width * this.scaleFactor.Ratio); } } public int SurfaceScrollableHeight { get { return (int)(this._compositionSurface.Height * this.scaleFactor.Ratio); } } public double ScaleRatio { get { return this.scaleFactor.Ratio; } } /// /// Returns a rectangle in screen coordinates that represents the space taken up /// by the document that is visible on screen. /// [Browsable(false)] public Rectangle VisibleDocumentBounds { get { // convert coordinates: document -> client -> screen return RectangleToScreen(Utility.RoundRectangle(DocumentToClient(VisibleDocumentRectangleF))); } } /// /// Returns a rectangle in client coordinates that denotes the space that the document /// may take up. This is essentially the ClientRectangle converted to screen coordinates /// and then with the rulers and scrollbars subtracted out. /// public Rectangle VisibleViewRectangle { get { Rectangle clientRect = this.panel.ClientRectangle; Rectangle screenRect = this.panel.RectangleToScreen(clientRect); Rectangle ourClientRect = RectangleToClient(screenRect); return ourClientRect; } } public Rectangle ClientRectangleMax { get { return RectangleToClient(this.panel.RectangleToScreen(this.panel.Bounds)); } } public Rectangle ClientRectangleMin { get { Rectangle bounds = ClientRectangleMax; bounds.Width -= SystemInformation.VerticalScrollBarWidth; bounds.Height -= SystemInformation.HorizontalScrollBarHeight; return bounds; } } public void SetHighlightRectangle(RectangleF rectF) { if (this.topRuler != null) { this.topRuler.HighlightStart = rectF.Left; this.topRuler.HighlightLength = rectF.Width; } if (this.leftRuler != null) { this.leftRuler.HighlightStart = rectF.Top; this.leftRuler.HighlightLength = rectF.Height; } } /// /// Gets or sets the Document that is shown through this instance of DocumentView. /// /// /// This property is thread safe and may be called from a non-UI thread. However, /// if the setter is called from a non-UI thread, then that thread will block as /// the call is marshaled to the UI thread. /// [Browsable(false)] public Document Document { get { return _document; } set { // Console.Write(string.Format("SetDocument-Start:{0};", DateTime.Now.Millisecond % 10000)); if (InvokeRequired) { this.Invoke(new Procedure(DocumentSetImpl), new object[2] { value, true }); } else { DocumentSetImpl(value, true); } // Console.WriteLine(string.Format("End:{0};", DateTime.Now.Millisecond % 10000)); } } public void setDoc(Document document, bool toeditori) { if (InvokeRequired) { this.Invoke(new Procedure(DocumentSetImpl), new object[2] { document, toeditori }); } else { DocumentSetImpl(document, toeditori); } } private void DocumentSetImpl(Document value, bool toedit) { this.DoubleBuffered = true; SetStyle(ControlStyles.OptimizedDoubleBuffer | ControlStyles.UserPaint | ControlStyles.AllPaintingInWmPaint, true); PointF dspf = DocumentScrollPositionF; OnDocumentChanging(value); // Console.Write(string.Format("DocumentChanged:{0};", DateTime.Now.Millisecond % 10000)); try { if (this._document != null) { this._document.Invalidated -= Document_Invalidated; this._document.Metadata.Changed -= DocumentMetaDataChangedHandler; } this._document = value; if (_document != null) { if (this._compositionSurface != null && this._compositionSurface.Size != _document.Size) { this._compositionSurface.Dispose(); this._compositionSurface = null; } //if (this.compositionSurface == null) //{ //this.compositionSurface = new Surface(Document.Size); if (!toedit && this._compositionSurface.Thumborigin != null) _document.surface.Thumborigin = OpenCvSharp.Extensions.BitmapConverter.ToBitmap(OpenCvSharp.Extensions.BitmapConverter.ToMat(this._compositionSurface.Thumborigin)); this._compositionSurface = _document.surface;//((BitmapLayer) this._document.Invalidated += Document_Invalidated; this._document.Metadata.Changed += DocumentMetaDataChangedHandler; } // Console.Write(string.Format("CreatedThumbnail:{0};", DateTime.Now.Millisecond % 10000)); Invalidate(true); DocumentMetaDataChangedHandler(this, EventArgs.Empty); this.OnResize(EventArgs.Empty); OnDocumentChanged(); } finally { } DocumentScrollPositionF = dspf; } public bool PanelAutoScroll { get { return panel.AutoScroll; } set { if (panel.AutoScroll != value) { panel.AutoScroll = value; } } } public DrawToolType ActiveTool { get => this.activeTool; set { tools[(int)activeTool].InvokeMember("beginWithNewObject", BindingFlags.Public | BindingFlags.Static | BindingFlags.InvokeMethod, null, null, new object[0] { }); if (value != DrawToolType.Pointer && this.appWorkspace.GetScriptRunning()) this.appWorkspace.SetScriptStopping(true); else if (value == DrawToolType.Pointer) { this.appWorkspace.SetScriptStopping(false); //this.appWorkspace.ResumeScriptRunning(); } if (value == DrawToolType.DrawGainNumber || value == DrawToolType.DrawDateMark || value == DrawToolType.DrawTimeMark || value == DrawToolType.DrawWaterMark || value == DrawToolType.DrawAutoRuler || value == DrawToolType.DrawPrestoredRuler) { this.activeTool = value; tools[(int)activeTool].InvokeMember("OnMouseDown", BindingFlags.Public | BindingFlags.Static | BindingFlags.InvokeMethod, null, null, new object[2] { this, null }); this.activeTool = DrawToolType.Pointer; } else { this.activeTool = value; } } } private void HookMouseEvents(Control c) { } private void DoLayout() { if (panel.ClientRectangle != new Rectangle(0, 0, 0, 0)) { int newX = panel.AutoScrollPosition.X; int newY = panel.AutoScrollPosition.Y; if (panel.ClientRectangle.Width > this.panel.Width) { newX = panel.AutoScrollPosition.X + ((panel.ClientRectangle.Width) / 2); } if (panel.ClientRectangle.Height > this.panel.Height) { newY = panel.AutoScrollPosition.Y + ((panel.ClientRectangle.Height) / 2); } } //暂时注释掉,因为在预览窗口、位置导航等显示标尺的时候,会闪烁,不知道会不会有啥问题 UpdateRulerOffsets(); } private void CheckForFirstInputAfterGotFocus() { if (this.raiseFirstInputAfterGotFocus) { this.raiseFirstInputAfterGotFocus = false; OnFirstInputAfterGotFocus(); } } private void Document_Invalidated(object sender, InvalidateEventArgs e) { if (this.ScaleFactor == ScaleFactor.OneToOne) { this.panel.Invalidate(e.InvalidRect); } else { Rectangle inflatedInvalidRect = Rectangle.Inflate(e.InvalidRect, 1, 1); Rectangle clientRect = this.panel.SurfaceToClient(inflatedInvalidRect); Rectangle inflatedClientRect = Rectangle.Inflate(clientRect, 1, 1); this.panel.Invalidate(inflatedClientRect); } } // Note: You use the Suspend/Resume pattern to suspend and resume refreshing (it hides the controls for a brief moment) // This is used by set_Document to avoid twitching/flickering in certain cases. // However, you should use Resume followed by Suspend to bypass the set_Document's use of that. // Interestingly, SaveConfigDialog does this to avoid 'blinking' when the save parameters are changed. /// /// 重新设置中心点 /// /// public void RecenterView(PointF newCenter) { RectangleF visibleRect = VisibleDocumentRectangleF; PointF cornerPt = new PointF( newCenter.X - (visibleRect.Width / 2), newCenter.Y - (visibleRect.Height / 2)); this.DocumentScrollPositionF = cornerPt; } /// /// 文档元数据改变事件 /// /// /// private void DocumentMetaDataChangedHandler(object sender, EventArgs e) { if (this._document != null) { this.leftRuler.Dpu = 1 / _document.PixelToPhysicalY(1, this.leftRuler.MeasurementUnit); this.topRuler.Dpu = 1 / _document.PixelToPhysicalY(1, this.topRuler.MeasurementUnit); } } #region 暂未用到的方法, 暂留 protected override bool ProcessCmdKey(ref Message msg, Keys keyData) { Keys keyCode = keyData & Keys.KeyCode; if (Utility.IsArrowKey(keyData) || keyCode == Keys.Delete || keyCode == Keys.Tab) { KeyEventArgs kea = new KeyEventArgs(keyData); // We only intercept WM_KEYDOWN because WM_KEYUP is not sent! switch (msg.Msg) { case 0x100: //NativeMethods.WmConstants.WM_KEYDOWN: if (this.ContainsFocus) { OnDocumentKeyDown(kea); //OnDocumentKeyUp(kea); if (Utility.IsArrowKey(keyData)) { kea.Handled = true; } } if (kea.Handled) { return true; } break; /* case 0x101: //NativeMethods.WmConstants.WM_KEYUP: if (this.ContainsFocus) { OnDocumentKeyUp(kea); } return kea.Handled; */ } } return base.ProcessCmdKey(ref msg, keyData); } private void MouseEnterHandler(object sender, EventArgs e) { OnDocumentMouseEnter(EventArgs.Empty); } private void MouseLeaveHandler(object sender, EventArgs e) { OnDocumentMouseLeave(EventArgs.Empty); } private void MouseMoveHandler(object sender, MouseEventArgs e) { Point docPoint = MouseToDocument((Control)sender, new Point(e.X, e.Y)); PointF docPointF = MouseToDocumentF((Control)sender, new Point(e.X, e.Y)); if (RulersEnabled) { int x; if (docPointF.X > 0) { x = (int)Math.Truncate(docPointF.X); } else if (docPointF.X < 0) { x = (int)Math.Truncate(docPointF.X - 1); } else // if (docPointF.X == 0) { x = 0; } int y; if (docPointF.Y > 0) { y = (int)Math.Truncate(docPointF.Y); } else if (docPointF.Y < 0) { y = (int)Math.Truncate(docPointF.Y - 1); } else // if (docPointF.Y == 0) { y = 0; } topRuler.Value = x; leftRuler.Value = y; UpdateRulerOffsets(); } OnDocumentMouseMove(new MouseEventArgs(e.Button, e.Clicks, docPoint.X, docPoint.Y, e.Delta)); } private void MouseUpHandler(object sender, MouseEventArgs e) { if (sender is RulerPro) { return; } Point docPoint = MouseToDocument((Control)sender, new Point(e.X, e.Y)); Point pt = panel.AutoScrollPosition; panel.Focus(); OnDocumentMouseUp(new MouseEventArgs(e.Button, e.Clicks, docPoint.X, docPoint.Y, e.Delta)); } private void MouseDownHandler(object sender, MouseEventArgs e) { if (sender is RulerPro) { return; } Point docPoint = MouseToDocument((Control)sender, new Point(e.X, e.Y)); Point pt = panel.AutoScrollPosition; panel.Focus(); OnDocumentMouseDown(new MouseEventArgs(e.Button, e.Clicks, docPoint.X, docPoint.Y, e.Delta)); } private void ClickHandler(object sender, EventArgs e) { Point pt = panel.AutoScrollPosition; panel.Focus(); OnDocumentClick(); } #endregion #region 对外的各种事件委托 // these events will report mouse coordinates in document space // i.e. if the image is zoomed at 200% then the mouse coordinates will be divided in half public event EventHandler CompositionUpdated; private void OnCompositionUpdated() { if (CompositionUpdated != null) { CompositionUpdated(this, EventArgs.Empty); } } public event EventHandler RulersEnabledChanged; protected void OnRulersEnabledChanged() { if (RulersEnabledChanged != null) { RulersEnabledChanged(this, EventArgs.Empty); } } public event EventHandler> DocumentChanging; protected virtual void OnDocumentChanging(Document newDocument) { if (DocumentChanging != null) { DocumentChanging(this, new EventArgs(newDocument)); } } public event EventHandler DocumentChanged; protected virtual void OnDocumentChanged() { if (DocumentChanged != null) { DocumentChanged(this, EventArgs.Empty); } } public event EventHandler FirstInputAfterGotFocus; protected virtual void OnFirstInputAfterGotFocus() { if (FirstInputAfterGotFocus != null) { FirstInputAfterGotFocus(this, EventArgs.Empty); } } /// /// Occurs when the mouse enters an element of the UI that is considered to be part of /// the document space. /// public event EventHandler DocumentMouseEnter; protected virtual void OnDocumentMouseEnter(EventArgs e) { if (DocumentMouseEnter != null) { DocumentMouseEnter(this, e); } } /// /// Occurs when the mouse leaves an element of the UI that is considered to be part of /// the document space. /// /// /// This event being raised does not necessarily correpond to the mouse leaving /// document space, only that it has left the screen space of an element of the UI /// that is part of document space. For example, if the mouse leaves the canvas and /// then enters the rulers, you will see a DocumentMouseLeave event raised which is /// then immediately followed by a DocumentMouseEnter event. /// public event EventHandler DocumentMouseLeave; protected virtual void OnDocumentMouseLeave(EventArgs e) { if (DocumentMouseLeave != null) { DocumentMouseLeave(this, e); } } /// /// Occurs when the mouse or stylus point is moved over the document. /// /// /// Note: This event will always be raised twice in succession. One will provide a /// MouseEventArgs, and the other will provide a StylusEventArgs. It is up to consumers /// of this event to decide which one is pertinent and to then filter out the other /// type of event. /// public event MouseEventHandler DocumentMouseMove; protected virtual void OnDocumentMouseMove(MouseEventArgs e) { if (DocumentMouseMove != null) { DocumentMouseMove(this, e); } } /// /// Occurs when the mouse or stylus point is over the document and a mouse button is released /// or the stylus is lifted. /// /// /// Note: This event will always be raised twice in succession. One will provide a /// MouseEventArgs, and the other will provide a StylusEventArgs. It is up to consumers /// of this event to decide which one is pertinent and to then filter out the other /// type of event. /// public event MouseEventHandler DocumentMouseUp; protected virtual void OnDocumentMouseUp(MouseEventArgs e) { CheckForFirstInputAfterGotFocus(); if (DocumentMouseUp != null) { DocumentMouseUp(this, e); } } /// /// Occurs when the mouse or stylus point is over the document and a mouse button or /// stylus is pressed. /// /// /// Note: This event will always be raised twice in succession. One will provide a /// MouseEventArgs, and the other will provide a StylusEventArgs. It is up to consumers /// of this event to decide which one is pertinent and to then filter out the other /// type of event. /// public event MouseEventHandler DocumentMouseDown; protected virtual void OnDocumentMouseDown(MouseEventArgs e) { CheckForFirstInputAfterGotFocus(); if (DocumentMouseDown != null) { DocumentMouseDown(this, e); } } public event EventHandler DocumentClick; protected void OnDocumentClick() { CheckForFirstInputAfterGotFocus(); if (DocumentClick != null) { DocumentClick(this, EventArgs.Empty); } } public event KeyPressEventHandler DocumentKeyPress; protected void OnDocumentKeyPress(KeyPressEventArgs e) { CheckForFirstInputAfterGotFocus(); if (DocumentKeyPress != null) { DocumentKeyPress(this, e); } } public event KeyEventHandler DocumentKeyDown; protected void OnDocumentKeyDown(KeyEventArgs e) { CheckForFirstInputAfterGotFocus(); if (DocumentKeyDown != null) { DocumentKeyDown(this, e); } } public event KeyEventHandler DocumentKeyUp; protected void OnDocumentKeyUp(KeyEventArgs e) { CheckForFirstInputAfterGotFocus(); if (DocumentKeyUp != null) { DocumentKeyUp(this, e); } } #endregion #region 多相相关 public List PhaseModels { set { this.phaseModels = value; this.appWorkspace.GetPanelBottom().documentStrip.ClearPhase(); this.appWorkspace.GetPanelBottom().documentStrip.AddPhase(this.phaseModels); } get { return this.phaseModels; } } /// /// 将物相和二值的数据带入到图像索引列表 /// public Bitmap BinarizationThumbnail { get { //二值化相关 if (this.phaseModels.Count == 0) return this.CompositionSurface.Thumbnail; else { Bitmap newBit = this.CompositionSurface.Thumbnail; Graphics graphics = Graphics.FromImage(newBit); for (int i = 0; i < this.phaseModels.Count; i++) { PhaseModel item = this.phaseModels[i]; if (item.choise && item.mat != null) graphics.DrawImage(OpenCvSharp.Extensions.BitmapConverter.ToBitmap(item.mat), 0, 0, newBit.Width, newBit.Height); } return newBit; } } } /// /// 将物相和二值的数据带入到分析页面 /// public PhaseModel AnalysisPhaseModel { get { //二值化相关 if (this.phaseModels.Count == 0) { return null; } else { OpenCvSharp.Mat multipleMat = null; int index = 0; for (index = 0; index < this.phaseModels.Count; index++) { PhaseModel item = this.phaseModels[index]; if (item.choise && item.mat != null) { multipleMat = item.mat; break; } } if (multipleMat == null) return null; Bitmap newBit = OpenCvSharp.Extensions.BitmapConverter.ToBitmap(multipleMat); Graphics graphics = Graphics.FromImage(newBit); for (int i = index + 1; i < this.phaseModels.Count; i++) { PhaseModel item = this.phaseModels[i]; if (item.choise && item.mat != null) { OpenCvSharp.Mat targetMat = item.mat; graphics.DrawImage(OpenCvSharp.Extensions.BitmapConverter.ToBitmap(targetMat), 0, 0, targetMat.Width, targetMat.Height); } } PhaseModel phaseModel = new PhaseModel(); phaseModel.name = this.PhaseModels[0].name; phaseModel.position = this.PhaseModels[0].position; phaseModel.color = this.PhaseModels[0].color; phaseModel.mat = OpenCvSharp.Extensions.BitmapConverter.ToMat(newBit); phaseModel.choise = true; phaseModel.rgborhls = this.PhaseModels[0].rgborhls; phaseModel.minB = this.PhaseModels[0].minB; phaseModel.maxB = this.PhaseModels[0].maxB; phaseModel.minG = this.PhaseModels[0].minG; phaseModel.maxG = this.PhaseModels[0].maxG; phaseModel.minR = this.PhaseModels[0].minR; phaseModel.maxR = this.PhaseModels[0].maxR; phaseModel.minH = this.PhaseModels[0].minH; phaseModel.maxH = this.PhaseModels[0].maxH; phaseModel.minL = this.PhaseModels[0].minL; phaseModel.maxL = this.PhaseModels[0].maxL; phaseModel.minS = this.PhaseModels[0].minS; phaseModel.maxS = this.PhaseModels[0].maxS; return phaseModel; } } } public List PhaseModelsForCopy { get { List list = new List(); if (this.phaseModels != null && this.phaseModels.Count > 0) { foreach (PhaseModel phase in this.phaseModels) { if (phase.mat == null)//跳过null的避免报错 continue; PhaseModel phase1 = new PhaseModel(); phase1.choise = phase.choise; phase1.color = phase.color; phase1.mat = new OpenCvSharp.Mat(); phase.mat.CopyTo(phase1.mat); phase1.name = phase.name; phase1.position = phase.position; list.Add(phase1); } } return list; } } #endregion #region DocimentView的子控件的事件 private void Panel_KeyPress(object sender, KeyPressEventArgs e) { OnDocumentKeyPress(e); } private void Panel_LostFocus(object sender, EventArgs e) { this.raiseFirstInputAfterGotFocus = false; } private void Panel_GotFocus(object sender, EventArgs e) { this.raiseFirstInputAfterGotFocus = true; } private void Panel_KeyDown(object sender, KeyEventArgs e) { if (e.KeyValue == 17) { this.controlPress = true; } CheckForFirstInputAfterGotFocus(); OnDocumentKeyDown(e); if (!e.Handled) { PointF oldPt = this.DocumentScrollPositionF; PointF newPt = oldPt; RectangleF vdr = VisibleDocumentRectangleF; switch (e.KeyData) { case Keys.Next: newPt.Y += vdr.Height; break; case (Keys.Next | Keys.Shift): newPt.X += vdr.Width; break; case Keys.Prior: newPt.Y -= vdr.Height; break; case (Keys.Prior | Keys.Shift): newPt.X -= vdr.Width; break; case Keys.Home: if (oldPt.X == 0) { newPt.Y = 0; } else { newPt.X = 0; } break; case Keys.End: if (vdr.Right < this._document.Width - 1) { newPt.X = this._document.Width; } else { newPt.Y = this._document.Height; } break; default: break; } if (newPt != oldPt) { DocumentScrollPositionF = newPt; e.Handled = true; } } } private void Panel_Scroll(object sender, System.Windows.Forms.ScrollEventArgs e) { OnScroll(e); UpdateRulerOffsets(); } private void Panel_KeyUp(object sender, KeyEventArgs e) { this.controlPress = false; OnDocumentKeyUp(e); } /// /// 鼠标按下事件 /// /// /// private void MouseEvent_Down(object sender, MouseEventArgs e) { //tools[(int)activeTool].OnMouseDown(this, e); tools[(int)activeTool].InvokeMember("OnMouseDown", BindingFlags.Public | BindingFlags.Static | BindingFlags.InvokeMethod, null, null, new object[2] { this, e }); if (this.appWorkspace != null) { this.appWorkspace.SetDrawNodes(); this.appWorkspace.RefreshCameraPriview(); } } public void MouseEvent_Del(object sender, MouseEventArgs e) { tools[(int)activeTool].InvokeMember("OnDelKeyDown", BindingFlags.Public | BindingFlags.Static | BindingFlags.InvokeMethod, null, null, new object[2] { this, e }); //tools[(int)activeTool].OnDelKeyDown(this, e); if (this.appWorkspace != null) this.appWorkspace.RefreshLabelListDialog(); } /// /// 鼠标移动事件 /// /// /// private void MouseEvent_Move(object sender, MouseEventArgs e) { // // 像素跟踪,如果AppWorkspace不等于null,坐标不超范围,则设置像素跟踪 // if (this.AppWorkspaceTop != null && this._compositionSurface != null && this.pixelTrackingEnabled) //&& e.Location.X>=0 && e.Location.Y>=0 //&& e.Location.X<=this.Surface.Width //&& e.Location.Y <= this.Surface.Height) { //this.AppWorkspaceTop.SetImageAndData(this.ScaleFactor.UnscalePoint(e.Location)); this.AppWorkspaceTop.SetImageAndData(this.CalcPixelPoint(e.Location)); } // // 是否绘制辅助线 // if (this.auxiliaryLineEnabled) { path = new GraphicsPath(); path.AddLine(new Point(0, e.Y), new Point(Width, e.Y)); path1 = new GraphicsPath(); path1.AddLine(new Point(e.X, 0), new Point(e.X, Height)); this.Refresh(); } // // 处理标注测量 // if (!initialized) return; if (e.Button == MouseButtons.Left || e.Button == MouseButtons.None) tools[(int)activeTool].InvokeMember("OnMouseMove", BindingFlags.Public | BindingFlags.Static | BindingFlags.InvokeMethod, null, null, new object[2] { this, e }); //tools[(int)activeTool].OnMouseMove(this, e); else this.Cursor = Cursors.Default; } /// /// 鼠标抬起事件 /// /// /// private void MouseEvent_Up(object sender, MouseEventArgs e) { if (e.Button == MouseButtons.Left) tools[(int)activeTool].InvokeMember("OnMouseUp", BindingFlags.Public | BindingFlags.Static | BindingFlags.InvokeMethod, null, null, new object[2] { this, e }); //tools[(int)activeTool].OnMouseUp(this, e); if (this.appWorkspace != null) { this.appWorkspace.RefreshLabelListDialog(); this.appWorkspace.RefreshListView(); this.appWorkspace.RefreshMeasureListView(); this.appWorkspace.RefreshOpticalDensity(); } } /// /// 鼠标单击事件 /// /// /// private void MouseEvent_Click(object sender, MouseEventArgs e) { tools[(int)activeTool].InvokeMember("OnMouseClick", BindingFlags.Public | BindingFlags.Static | BindingFlags.InvokeMethod, null, null, new object[2] { this, e }); //tools[(int)activeTool].OnMouseClick(this, e); } /// /// 鼠标双击事件 /// /// /// private void MouseEvent_DoubleClick(object sender, MouseEventArgs e) { if (e.Button == MouseButtons.Left && e.Clicks == 2) { if (this.controlPress) { List list = this.graphicsList.GetDrawToolTypeList(DrawToolType.ImageCut); if (list != null && list.Count > 0) { Point ene = GetScalePoint(e.Location); RectangleF rect = list[0].Rectangle; if (ene.X > rect.X && ene.X < (rect.X + rect.Width) && ene.Y > rect.Y && ene.Y < (rect.Y + rect.Height)) { this.appWorkspace.CopyAndPasteByControlAndDoubleClick(); } } this.controlPress = false; } else { tools[(int)activeTool].InvokeMember("OnMouseLeftDoubleClick", BindingFlags.Public | BindingFlags.Static | BindingFlags.InvokeMethod, null, null, new object[2] { this, e }); } } //tools[(int)activeTool].OnMouseLeftDoubleClick(this, e); } /// /// 获取panel显示内容 生成图片返回 /// /// public Bitmap panelBitmap() { if (_compositionSurface == null) { return null; } Bitmap origin = _compositionSurface.CreateAliasedBitmap(); Bitmap newBit = null; int width = newBit.Width;// (int)(this.compositionSurface.Width * this.scaleFactor.Ratio); int height = newBit.Height;// (int)(this.compositionSurface.Height * this.scaleFactor.Ratio); int x = 0;// (rc.Width < width) ? this.panel.AutoScrollPosition.X + offsetHalfW : (rc.Width - width) / 2; int y = 0;// (rc.Height < height) ? this.panel.AutoScrollPosition.Y + offsetHalfH : (rc.Height - height) / 2; Graphics graphics = Graphics.FromImage(newBit); // // 以下是绘制相 // if (phaseModels.Count > 0) { foreach (PhaseModel model in phaseModels) { if (model != null && model.choise && model.mat != null) { Bitmap map = OpenCvSharp.Extensions.BitmapConverter.ToBitmap(model.mat); graphics.DrawImage(map, x, y, width, height); } } } // // 以下是绘制辅助线 // if (this.auxiliaryLineEnabled) { if (path != null && path1 != null) { graphics.DrawPath(new Pen(Color.Red), path); graphics.DrawPath(new Pen(Color.Red), path1); } } // // 以下是绘制网格、标注、测量、视场等开始 // graphics.TranslateTransform(x, y); graphics.ScaleTransform((float)1.0/*this.scaleFactor.Ratio*/, (float)1.0/*this.scaleFactor.Ratio*/); // // 以下是绘制网格 // if (this.gridLineEnabled && this.AppWorkspaceTop != null) { double unitLength = 1; this.appWorkspace.getMeasureInfo().TryGetValue(MeasurementUnit.Micron, out unitLength); int unit = AppWorkspaceTop.GetGridModel().grid.Unit; //单位 int actualLength = AppWorkspaceTop.GetGridModel().grid.ActualLength;//实际长度 if (unit == (int)MeasurementUnit.Micron) { AppWorkspaceTop.GetGridModel().grid.SideLength = (int)((double)actualLength / unitLength); } //else if (unit == (int)MeasurementUnit.Pixel) //{ // AppWorkspaceTop.GetGridModel().grid.SideLength = actualLength; //} DrawRulerHelper.drawGrid(AppWorkspaceTop.GetGridModel(), graphics, this._compositionSurface.Width, this._compositionSurface.Height); } // //以下是绘制矩形网格 // if (this.gridRectangleEnabled && this.AppWorkspaceTop != null && micronRatio > 0) { DrawRulerHelper.drawGridRectangle(AppWorkspaceTop.GetGridModel(), graphics, this._compositionSurface.Width, this._compositionSurface.Height, micronRatio); } // //以下是绘制圆形网格 // if (this.gridRoundEnabled && this.AppWorkspaceTop != null && micronRatio > 0) { DrawRulerHelper.drawGridRound(AppWorkspaceTop.GetGridModel(), graphics, this._compositionSurface.Width, this._compositionSurface.Height, micronRatio); } // //以下是绘制十字线 // if (this.gridCrossCurveEnabled && this.AppWorkspaceTop != null) { DrawRulerHelper.drawGridCrossCurve(null, graphics, this._compositionSurface.Width, this._compositionSurface.Height); } // // 以下是绘制标注、测量、视场 // if (graphicsList != null) { graphicsList.Draw(graphics); } // // 以下是绘制网格(覆盖整个图片) // if (this.gridLineFullEnabled && this.AppWorkspaceTop != null) { DrawRulerHelper.drawGridFull(AppWorkspaceTop.GetGridModel(), graphics, this._compositionSurface.Width, this._compositionSurface.Height); } // // 以下是绘制图像(工艺图比照定位点图像绘制) // if (m_selectedBitmap != null) { graphics.DrawImage(m_selectedBitmap, new PointF(m_artworkImageRectangle.X, m_artworkImageRectangle.Y)); } return newBit; } /// /// 获取panel显示内容 生成图片返回 /// /// public Bitmap NewPanelBitmap(Bitmap newBit) { int width = newBit.Width;// (int)(this.compositionSurface.Width * this.scaleFactor.Ratio); int height = newBit.Height;// (int)(this.compositionSurface.Height * this.scaleFactor.Ratio); int x = 0;// (rc.Width < width) ? this.panel.AutoScrollPosition.X + offsetHalfW : (rc.Width - width) / 2; int y = 0;// (rc.Height < height) ? this.panel.AutoScrollPosition.Y + offsetHalfH : (rc.Height - height) / 2; Graphics graphics = Graphics.FromImage(newBit); // // 以下是绘制相 // if (phaseModels.Count > 0) { foreach (PhaseModel model in phaseModels) { if (model != null && model.choise && model.mat != null) { Bitmap map = OpenCvSharp.Extensions.BitmapConverter.ToBitmap(model.mat); graphics.DrawImage(map, x, y, width, height); } } } // // 以下是绘制辅助线 // //if (this.auxiliaryLineEnabled) //{ // if (path != null && path1 != null) // { // graphics.DrawPath(new Pen(Color.Red), path); // graphics.DrawPath(new Pen(Color.Red), path1); // } //} // // 以下是绘制网格、标注、测量、视场等开始 // graphics.TranslateTransform(x, y); graphics.ScaleTransform((float)1.0/*this.scaleFactor.Ratio*/, (float)1.0/*this.scaleFactor.Ratio*/); // // 以下是绘制网格 // if (this.gridLineEnabled && this.AppWorkspaceTop != null) { double unitLength = 1; this.appWorkspace.getMeasureInfo().TryGetValue(MeasurementUnit.Micron, out unitLength); int unit = AppWorkspaceTop.GetGridModel().grid.Unit; //单位 int actualLength = AppWorkspaceTop.GetGridModel().grid.ActualLength;//实际长度 if (unit == (int)MeasurementUnit.Micron) { AppWorkspaceTop.GetGridModel().grid.SideLength = (int)((double)actualLength / unitLength); } //else if (unit == (int)MeasurementUnit.Pixel) //{ // AppWorkspaceTop.GetGridModel().grid.SideLength = actualLength; //} DrawRulerHelper.drawGrid(AppWorkspaceTop.GetGridModel(), graphics, this._compositionSurface.Width, this._compositionSurface.Height); } // //以下是绘制矩形网格 // if (this.gridRectangleEnabled && this.AppWorkspaceTop != null && micronRatio > 0) { DrawRulerHelper.drawGridRectangle(AppWorkspaceTop.GetGridModel(), graphics, this._compositionSurface.Width, this._compositionSurface.Height, micronRatio); } // //以下是绘制圆形网格 // if (this.gridRoundEnabled && this.AppWorkspaceTop != null && micronRatio > 0) { DrawRulerHelper.drawGridRound(AppWorkspaceTop.GetGridModel(), graphics, this._compositionSurface.Width, this._compositionSurface.Height, micronRatio); } // //以下是绘制十字线 // if (this.gridCrossCurveEnabled && this.AppWorkspaceTop != null) { DrawRulerHelper.drawGridCrossCurve(null, graphics, this._compositionSurface.Width, this._compositionSurface.Height); } // // 以下是绘制标注、测量、视场 // if (graphicsList != null) { graphicsList.Draw(graphics); } // // 以下是绘制网格(覆盖整个图片) // if (this.gridLineFullEnabled && this.AppWorkspaceTop != null) { DrawRulerHelper.drawGridFull(AppWorkspaceTop.GetGridModel(), graphics, this._compositionSurface.Width, this._compositionSurface.Height); } // // 以下是绘制图像(工艺图比照定位点图像绘制) // if (m_selectedBitmap != null) { graphics.DrawImage(m_selectedBitmap, new PointF(m_artworkImageRectangle.X, m_artworkImageRectangle.Y)); } return newBit; } /// /// 获取panel标注、测量、视场显示内容 生成图片返回 /// /// public Bitmap FieldBitmap(Bitmap newBit) { int width = newBit.Width;// (int)(this.compositionSurface.Width * this.scaleFactor.Ratio); int height = newBit.Height;// (int)(this.compositionSurface.Height * this.scaleFactor.Ratio); int x = 0;// (rc.Width < width) ? this.panel.AutoScrollPosition.X + offsetHalfW : (rc.Width - width) / 2; int y = 0;// (rc.Height < height) ? this.panel.AutoScrollPosition.Y + offsetHalfH : (rc.Height - height) / 2; Graphics graphics = Graphics.FromImage(newBit); // // 以下是绘制网格、标注、测量、视场等开始 // graphics.TranslateTransform(x, y); graphics.ScaleTransform((float)1.0/*this.scaleFactor.Ratio*/, (float)1.0/*this.scaleFactor.Ratio*/); // // 以下是绘制标注、测量、视场 // if (graphicsList != null) { graphicsList.Draw(graphics); } return newBit; } /// /// 样式信息 /// //private GuideStyleModel guideStyleModel; /// /// 绘制事件 /// /// /// private void panelPaint(object sender, PaintEventArgs e) { // Console.Write(string.Format("DrawStart:{0};", DateTime.Now.Millisecond % 10000)); if (_compositionSurface != null) { // 以下是计算绘制图片的位置和大小并绘制图片 Rectangle rc = this.panel.ClientRectangle; int width = (int)(this._compositionSurface.Width * this.scaleFactor.Ratio); int height = (int)(this._compositionSurface.Height * this.scaleFactor.Ratio); int x = (rc.Width < width) ? _offsetHalfW : (rc.Width - width) / 2; int y = (rc.Height < height) ? _offsetHalfH : (rc.Height - height) / 2; var img = _compositionSurface.CreateAliasedBitmap(false); if (img != null) { e.Graphics.DrawImage(img, (float)m_pLeft, (float)m_pTop, (rc.Width < width) ? rc.Width : width, (rc.Height < height) ? rc.Height : height); } // 绘制选择的矩形 if (drawRectangle) { /*Pen pen = new Pen(Color.Black); pen.DashStyle = DashStyle.Dot;*/ e.Graphics.DrawRectangle(new Pen(Color.Black), this.DrawRectangle); } // 以下是绘制相 if (phaseModels.Count > 0) { foreach (PhaseModel model in phaseModels) { if (model != null && model.choise && model.mat != null) { Bitmap map = OpenCvSharp.Extensions.BitmapConverter.ToBitmap(model.mat); e.Graphics.DrawImage(map, x, y, width, height); } } } // // 以下是绘制辅助线 // if (this.auxiliaryLineEnabled) { if (path != null && path1 != null) { Pen linePen = new Pen(Color.FromArgb(GetGuideStyleModel().lineColour), (float)GetGuideStyleModel().lineWidth); linePen.DashStyle = (DashStyle)GetGuideStyleModel().lineStyle; e.Graphics.DrawPath(linePen, path); e.Graphics.DrawPath(linePen, path1); } } // // 以下是绘制网格、标注、测量、视场等开始 // e.Graphics.TranslateTransform(x, y); e.Graphics.ScaleTransform((float)this.scaleFactor.Ratio, (float)this.scaleFactor.Ratio); // // 以下是绘制网格 // if (this.gridLineEnabled && this.AppWorkspaceTop != null) { //double unitLength = 1; //this.appWorkspace.getMeasureInfo().TryGetValue(MeasurementUnit.Micron, out unitLength); double unitLength = this.GetRuler(MeasurementUnit.Micron); //获取标尺 int unit = AppWorkspaceTop.GetGridModel().grid.Unit; //单位 int actualLength = AppWorkspaceTop.GetGridModel().grid.ActualLength; //实际长度 if (unit == (int)MeasurementUnit.Micron) { AppWorkspaceTop.GetGridModel().grid.SideLength = (int)((double)actualLength / unitLength); } //else if (unit == (int)MeasurementUnit.Pixel) //{ // AppWorkspaceTop.GetGridModel().grid.SideLength = actualLength; //} DrawRulerHelper.drawGrid(AppWorkspaceTop.GetGridModel(), e.Graphics, this._compositionSurface.Width, this._compositionSurface.Height); } // //以下是绘制矩形网格 // if (this.gridRectangleEnabled && this.AppWorkspaceTop != null && micronRatio > 0) { DrawRulerHelper.drawGridRectangle(AppWorkspaceTop.GetGridModel(), e.Graphics, this._compositionSurface.Width, this._compositionSurface.Height, micronRatio); } // //以下是绘制圆形网格 // if (this.gridRoundEnabled && this.AppWorkspaceTop != null && micronRatio > 0) { DrawRulerHelper.drawGridRound(AppWorkspaceTop.GetGridModel(), e.Graphics, this._compositionSurface.Width, this._compositionSurface.Height, micronRatio); } // //以下是绘制十字线 // if (this.gridCrossCurveEnabled && this.AppWorkspaceTop != null) { DrawRulerHelper.drawGridCrossCurve(null, e.Graphics, this._compositionSurface.Width, this._compositionSurface.Height); } // // 以下是绘制标注、测量、视场 // if (graphicsList != null) { graphicsList.Draw(e.Graphics); } // // 以下是绘制网格(覆盖整个图片) // if (this.gridLineFullEnabled && this.AppWorkspaceTop != null) { DrawRulerHelper.drawGridFull(AppWorkspaceTop.GetGridModel(), e.Graphics, this._compositionSurface.Width, this._compositionSurface.Height); } // // 以下是绘制图像(工艺图比照定位点图像绘制) // if (m_selectedBitmap != null) { e.Graphics.DrawImage(m_selectedBitmap, new PointF(m_artworkImageRectangle.X, m_artworkImageRectangle.Y)); } e.Graphics.ScaleTransform(1 / (float)this.scaleFactor.Ratio, 1 / (float)this.scaleFactor.Ratio); e.Graphics.TranslateTransform(-x, -y); } //Console.WriteLine(string.Format("End:{0};", DateTime.Now.Millisecond % 10000)); } #endregion #region DocumentView的事件 protected override void OnLayout(LayoutEventArgs e) { DoLayout(); base.OnLayout(e); } /// /// 让画布获取焦点 /// public new void Focus() { this.panel.Focus(); } protected override void OnResize(EventArgs e) { // enable or disable timer: no sense drawing selection if we're minimized Form parentForm = ParentForm; if (parentForm != null) { if (parentForm.WindowState != this.oldWindowState) { PerformLayout(); } this.oldWindowState = parentForm.WindowState; } base.OnResize(e); DoLayout(); } #endregion #region 坐标转换相关方法 public PointF MouseToDocumentF(Control sender, Point mouse) { Point screenPoint = sender.PointToScreen(mouse); Point sbClient = this.panel.PointToClient(screenPoint); PointF docPoint = this.panel.ClientToSurface(new PointF(sbClient.X, sbClient.Y)); return docPoint; } public Point MouseToDocument(Control sender, Point mouse) { Point screenPoint = sender.PointToScreen(mouse); Point sbClient = this.panel.PointToClient(screenPoint); Point docPoint = Point.Truncate(this.panel.ClientToSurface(sbClient)); return docPoint; } /// /// Converts a point from the Windows Forms "client" coordinate space (wrt the DocumentView) /// into the Document coordinate space. /// /// A Point that is in our client coordinates. /// A Point that is in Document coordinates. public PointF ClientToDocument(Point clientPt) { Point screen = PointToScreen(clientPt); Point sbClient = this.panel.PointToClient(screen); return this.panel.ClientToSurface(sbClient); } /// /// Converts a point from screen coordinates to document coordinates /// /// The point in screen coordinates to convert to document coordinates public PointF ScreenToDocument(PointF screen) { Point offset = this.panel.PointToClient(new Point(0, 0)); return this.panel.ClientToSurface(new PointF(screen.X + (float)offset.X, screen.Y + (float)offset.Y)); } /// /// Converts a point from screen coordinates to document coordinates /// /// The point in screen coordinates to convert to document coordinates public Point ScreenToDocument(Point screen) { Point offset = this.panel.PointToClient(new Point(0, 0)); return this.panel.ClientToSurface(new Point(screen.X + offset.X, screen.Y + offset.Y)); } /// /// Converts a PointF from the RealTimeStylus coordinate space /// into the Document coordinate space. /// /// A Point that is in RealTimeStylus coordinate space. /// A Point that is in Document coordinates. public PointF ClientToSurface(PointF clientPt) { return this.panel.ClientToSurface(clientPt); } /// /// Converts a point from Document coordinate space into the Windows Forms "client" /// coordinate space. /// /// A Point that is in Document coordinates. /// A Point that is in client coordinates. public PointF DocumentToClient(PointF documentPt) { PointF sbClient = this.panel.SurfaceToClient(documentPt); Point screen = this.panel.PointToScreen(Point.Round(sbClient)); return PointToClient(screen); } /// /// Converts a rectangle from the Windows Forms "client" coordinate space into the Document /// coordinate space. /// /// A Rectangle that is in client coordinates. /// A Rectangle that is in Document coordinates. public RectangleF ClientToDocument(Rectangle clientRect) { Rectangle screen = RectangleToScreen(clientRect); screen.X = screen.X + _offsetW; screen.Y = screen.Y + _offsetH; Rectangle sbClient = this.panel.RectangleToClient(screen); return this.panel.ClientToSurface((RectangleF)sbClient); } /// /// Converts a rectangle from Document coordinate space into the Windows Forms "client" /// coordinate space. /// /// A Rectangle that is in Document coordinates. /// A Rectangle that is in client coordinates. public RectangleF DocumentToClient(RectangleF documentRect) { RectangleF sbClient = this.panel.SurfaceToClient(documentRect); Rectangle screen = this.panel.RectangleToScreen(Utility.RoundRectangle(sbClient)); return RectangleToClient(screen); } public Rectangle SurfaceToClient(Rectangle surfaceRect) { return new Rectangle(SurfaceToClient(surfaceRect.Location), SurfaceToClient(surfaceRect.Size)); } public Point SurfaceToClient(Point surfacePt) { return ScaleFactor.ScalePoint(surfacePt); } public Size SurfaceToClient(Size surfaceSize) { return Size.Round(SurfaceToClient((SizeF)surfaceSize)); } public SizeF SurfaceToClient(SizeF surfaceSize) { return ScaleFactor.ScaleSize(surfaceSize); } #endregion #region 接口实现 public void IsDirty(GraphicsList gList) { this.AdjustRendering(); } public RectangleF GetVisibleDocumentRectangleF() { return this.AppWorkspaceTop.GetVisibleDocumentRectangleF(); } public SizeF GetDocumentSize() { return this.AppWorkspaceTop.GetDocumentSize(); } /// /// 添加到标注测量历史 /// /// public void AddCommandToHistory(Command c) { this.undoManager.AddCommandToHistory(c); } /// /// 初始化标注测量管理 /// public void ResetUndoManager() { this.undoManager = new UndoManager(this.GraphicsList); } /// /// 标注连续绘制标记 /// /// bool ISurfaceBox.ContinuousDrawingLabel() { return ContinuousDrawingLabel; } /// /// 测量连续绘制标记 /// /// bool ISurfaceBox.ContinuousDrawingMeasure() { return ContinuousDrawingMeasure; } /// /// 实际大小标记 /// /// bool ISurfaceBox.ActualSize() { return ActualSize; } /// /// 合适大小标记 /// /// bool ISurfaceBox.SuitableSize() { return SuitableSize; } /// /// 合适高度标记 /// /// bool ISurfaceBox.SuitableHeight() { return SuitableHeight; } /// /// 合适大小宽度标记 /// /// bool ISurfaceBox.SuitableWidth() { return SuitableWidth; } /// /// 图片扩缩 /// /// bool ISurfaceBox.LockZoom() { return LockZoom; } /// /// 定倍显示 /// /// bool ISurfaceBox.FixedMultiple() { return FixedMultiple; } /// /// 合并视场 /// /// bool ISurfaceBox.MergeFieldOfView() { return MergeFieldOfView; } /// /// 删除视场 /// /// bool ISurfaceBox.DeleteFieldOfView() { return DeleteFieldOfView; } /// /// 二值操作连续绘制标记 /// /// bool ISurfaceBox.ContinuousBinaryAction() { return ContinuousBinaryAction; } public PointF ClientToSurface(Point sbClient) { return ScaleFactor.UnscalePoint(sbClient); //return this.ClientToSurface(sbClient); } public void SetDirty() { this.Document.Dirty = true; } /// /// 获取原始坐标点 /// /// public Point GetCalcOriginPoint() { Rectangle rc = this.panel.ClientRectangle; int width = (int)(this._compositionSurface.Width * this.scaleFactor.Ratio); int height = (int)(this._compositionSurface.Height * this.scaleFactor.Ratio); int x = (rc.Width < width) ? this.panel.AutoScrollPosition.X + _offsetHalfW : (rc.Width - width) / 2; int y = (rc.Height < height) ? this.panel.AutoScrollPosition.Y + _offsetHalfH : (rc.Height - height) / 2; return new Point(x, y); } /// /// 获取未缩放的坐标点 /// /// /// public Point GetScalePoint(PointF point) { Rectangle rc = this.panel.ClientRectangle; int width = this._compositionSurface == null ? 800 : (int)(this._compositionSurface.Width * this.scaleFactor.Ratio); int height = this._compositionSurface == null ? 600 : (int)(this._compositionSurface.Height * this.scaleFactor.Ratio); int x = (rc.Width < width) ? this.panel.AutoScrollPosition.X + _offsetHalfW : (rc.Width - width) / 2; int y = (rc.Height < height) ? this.panel.AutoScrollPosition.Y + _offsetHalfH : (rc.Height - height) / 2; return new Point( (int)((point.X - x) / this.scaleFactor.Ratio), (int)((point.Y - y) / this.scaleFactor.Ratio) ); //return this.scaleFactor.UnscalePoint(location); } public int UnscaleScalar(int deltaX) { return this.scaleFactor.UnscaleScalar(deltaX); } /// /// 获取标注样式 /// /// public LabelStyleModel GetLabelStyleModel() { return this.AppWorkspaceTop.GetLabelStyleModel(); } public PointF GetDocumentScrollPositionF() { return this.DocumentScrollPositionF; //return this.AppWorkspaceTop.GetDocumentScrollPositionF(); } public void SetDocumentScrollPositionF(PointF newScrollPos) { //PointF sbClientF = this.panel.SurfaceToClient(newScrollPos); //Point sbClient = Point.Round(sbClientF); Point sbClient = Point.Round(newScrollPos); if (this.panel.AutoScrollPosition != new Point(-sbClient.X, -sbClient.Y)) { this.panel.AutoScrollPosition = sbClient; UpdateRulerOffsets(); //this.panelBottom.Invalidate(); this.topRuler.Invalidate(); this.leftRuler.Invalidate(); } /*PointF sbClientF = this.panel.SurfaceToClient(value); Point sbClient = Point.Round(sbClientF); if (this.panel.AutoScrollPosition != new Point(-sbClient.X, -sbClient.Y)) { this.panel.AutoScrollPosition = sbClient; UpdateRulerOffsets(); this.topRuler.Invalidate(); this.leftRuler.Invalidate(); }*/ //this.AppWorkspaceTop.SetDocumentScrollPositionF(newScrollPos); } public string[] GetPxPerUnit() { return this.AppWorkspaceTop.GetPxPerUnit();//getRulerList();//. } public Dictionary GetUnitsDictionary() { return InvariantData.unitsDictionary; } public Dictionary GetUnitSymbolsDictionary() { return InvariantData.unitSymbolsDictionary; } public Dictionary getMeasureInfo() { if (this.rules.Count > 0) return this.rules; else return this.AppWorkspaceTop.getMeasureInfo(); } /// /// 获取测量的样式 /// /// public MeasureStyleModel GetMeasureStyleModel() { return this.AppWorkspaceTop.GetMeasureStyleModel(); } /// /// 获取设置-常规设置-辅助线样式信息 /// /// public GuideStyleModel GetGuideStyleModel() { return this.AppWorkspaceTop.GetGuideStyleModel(); } /// /// 获取水印样式 /// /// public WatermarkModel GetWatermarkModel() { return this.AppWorkspaceTop.GetWatermarkModel(); } /// /// 获取工型样式 /// /// public WorkTypeStyleModel GetWorkTypeStyleModel() { return this.AppWorkspaceTop.GetWorkTypeStyleModel(); } /// /// 获取标尺样式 /// /// public RulerModel GetRulerStyleModel() { return this.AppWorkspaceTop.GetRulerStyleModel(); } /// /// 获取视场的状态,合并/剪切 /// /// public CombineMode GetCombineMode() { return this.AppWorkspaceTop.GetCombineMode(); } /// /// 设置当前鼠标的状态 /// /// public void SetMouseStatus(bool status) { this.mouseStatus = status; } /// /// 获取当前鼠标的状态 /// public bool GetMouseStatus() { return this.mouseStatus; } public int GetSegmentationWidth() { return InvariantData.segmentation; } public int GetConnectionWidth() { return InvariantData.connection; } public decimal GetGainMultiple() { return this.AppWorkspaceTop.GetGainMultiple(); } /// /// 刷新标注列表 /// public void RefreshLabelListDialog() { this.AppWorkspaceTop.RefreshLabelListDialog(); } /// /// 更新命名的延续数字 /// public void UpdateContinueNum() { this.AppWorkspaceTop.UpdateContinueNum(); } #endregion #region 二值操作,对象处理 /// /// 预处理 - 交互操作 - 单个提取 /// /// public void BinaryActionExtract(PointF point) { PointF point1 = GetScalePoint(point); if (point1.X >= 0 && point1.Y >= 0 && point1.X < this.CompositionSurface.Width && point1.Y < this.CompositionSurface.Height) { List choiseList = this.phaseModels.FindAll(a => a.choise == true); //如果已经存在并选择了相,则在相处理,如果选择多个相,默认最后一个相 if (this.phaseModels != null && this.phaseModels.Count > 0 && choiseList.Count > 0) { Color color = Color.FromArgb(choiseList[0].color); choiseList[0].mat = PreActionIntent.SingleExtract(OpenCvSharp.Extensions.BitmapConverter.ToMat(this._compositionSurface.CreateAliasedBitmap()), choiseList[0].mat, point1, new OpenCvSharp.Vec4b(color.B, color.G, color.R, 255)); this.panel.Refresh(); } //如果不存在相或者没有选择相,则在原图上处理 else { PhaseModel model = new PhaseModel(); model.choise = true; model.color = Color.Red.ToArgb(); model.position = 0; model.name = "phase0"; model.mat = PreActionIntent.SingleExtract(OpenCvSharp.Extensions.BitmapConverter.ToMat(this._compositionSurface.CreateAliasedBitmap()), null, point1, new OpenCvSharp.Vec4b(0, 0, 255, 255)); List list = new List(); list.Add(model); this.PhaseModels = list; this.panel.Refresh(); } } } /// /// 预处理 - 交互操作 - 选择 - 反选 /// public void BinaryActionAntiElection(int j) { OpenCvSharp.Mat[] arr = this.phaseModels[j].mat.Split(); arr[0] = ~arr[0]; arr[1] = ~arr[1]; arr[2] = ~arr[1]; OpenCvSharp.Cv2.Merge(arr, this.phaseModels[j].mat); this.panel.Refresh(); } /// /// 预处理 - 交互操作 - 选择 - 应用 /// 原有的相颜色变透明,保留反色的 /// public void BinaryActionAntiConfirm(int j) { this.phaseModels[j].mat = PreActionIntent.BinaryActionAntiConfirm(this.phaseModels[j].mat, this.phaseModels[j].color); this.panel.Refresh(); } /// /// 预处理 - 交互操作 - 选择 - 单个选择 /// /// public void BinaryActionChoise(PointF point) { Point point1 = GetScalePoint(point); if (point1.X >= 0 && point1.Y >= 0 && point1.X < this.CompositionSurface.Width && point1.Y < this.CompositionSurface.Height) { List choiseList = this.phaseModels.FindAll(a => a.choise == true); if (this.phaseModels != null && this.phaseModels.Count > 0 && choiseList.Count > 0) { foreach (PhaseModel phaseModel in choiseList) { phaseModel.mat = PreActionIntent.SingleChoise(phaseModel.mat, phaseModel.color, point1); this.panel.Refresh(); } } } } /// /// 预处理 - 交互操作 - 选择 - 矩形选择 /// /// public void BinaryActionChoiseRectangle(RectangleF rectangle) { List choiseList = this.phaseModels.FindAll(a => a.choise == true); if (this.phaseModels != null && this.phaseModels.Count > 0 && choiseList.Count > 0) { foreach (PhaseModel phaseModel in choiseList) { phaseModel.mat = PreActionIntent.SingleChoiseRectangle(phaseModel.mat, phaseModel.color, rectangle); this.panel.Refresh(); } } } /// /// 预处理 - 交互操作 - 选择 - 椭圆选择 /// /// public void BinaryActionChoiseOval(RectangleF rectangle) { List choiseList = this.phaseModels.FindAll(a => a.choise == true); if (this.phaseModels != null && this.phaseModels.Count > 0 && choiseList.Count > 0) { foreach (PhaseModel phaseModel in choiseList) { phaseModel.mat = PreActionIntent.SingleChoiseOval(phaseModel.mat, phaseModel.color, rectangle); this.panel.Refresh(); } } } /// /// 预处理 - 交互操作 - 选择 - 多边形选择 /// /// public void BinaryActionChoisePolygon(List points) { List choiseList = this.phaseModels.FindAll(a => a.choise == true); if (this.phaseModels != null && this.phaseModels.Count > 0 && choiseList.Count > 0) { foreach (PhaseModel phaseModel in choiseList) { phaseModel.mat = PreActionIntent.SingleChoisePolygon(phaseModel.mat, phaseModel.color, points); this.panel.Refresh(); } } } /// /// 预处理 - 交互操作 - 删除 - 单个删除 /// /// public void BinaryActionDelete(PointF point) { Point point1 = GetScalePoint(point); if (point1.X >= 0 && point1.Y >= 0 && point1.X < this.CompositionSurface.Width && point1.Y < this.CompositionSurface.Height) { List choiseList = this.phaseModels.FindAll(a => a.choise == true); if (this.phaseModels != null && this.phaseModels.Count > 0 && choiseList.Count > 0) { foreach (PhaseModel p in choiseList) { Color color = Color.FromArgb(p.color); int c = (color.R > color.G) ? ((color.R > color.B) ? color.R : color.B) : ((color.G > color.B) ? color.G : color.B); p.mat = PreActionIntent.SingleDelete(p.mat, point1, c); this.panel.Refresh(); } } } } /// /// 预处理 - 交互操作 - 删除 - 矩形删除 /// /// public void BinaryActionDelete(RectangleF rect) { List choiseList = this.phaseModels.FindAll(a => a.choise == true); if (this.phaseModels != null && this.phaseModels.Count > 0 && choiseList.Count > 0) { foreach (PhaseModel p in choiseList) { p.mat = PreActionIntent.RectangleDelete(p.mat, rect); this.panel.Refresh(); } } } /// /// 预处理 - 交互操作 - 删除 - 椭圆删除 /// /// public void BinaryActionDeleteOval(RectangleF rect) { List choiseList = this.phaseModels.FindAll(a => a.choise == true); if (this.phaseModels != null && this.phaseModels.Count > 0 && choiseList.Count > 0) { foreach (PhaseModel p in choiseList) { p.mat = PreActionIntent.OvalDelete(p.mat, rect); this.panel.Refresh(); } } } /// /// 预处理 - 交互操作 - 删除 - 多边形删除 /// /// public void BinaryActionDelete(List points) { List choiseList = this.phaseModels.FindAll(a => a.choise == true); if (this.phaseModels != null && this.phaseModels.Count > 0 && choiseList.Count > 0) { foreach (PhaseModel p in choiseList) { p.mat = PreActionIntent.PolygonDelete(p.mat, points); this.panel.Refresh(); } } } /// /// 预处理 - 交互操作 - 直线分割 /// public void BinaryActionSplitLine(PointF start, PointF end) { List choiseList = this.phaseModels.FindAll(a => a.choise == true); if (this.phaseModels != null && this.phaseModels.Count > 0 && choiseList.Count > 0) { foreach (PhaseModel p in choiseList) { p.mat = PreActionIntent.LineSplit(p.mat, start, end, InvariantData.segmentation); this.panel.Refresh(); } } } /// /// 预处理 - 连接 - 直线 /// /// /// public void BinaryActionConnectionLine(PointF start, PointF end) { List choiseList = this.phaseModels.FindAll(a => a.choise == true); if (this.phaseModels != null && this.phaseModels.Count > 0 && choiseList.Count > 0) { foreach (PhaseModel p in choiseList) { p.mat = PreActionIntent.LineConnection(p.mat, p.color, start, end, InvariantData.connection); this.panel.Refresh(); } } } /// /// 预处理 - 连接 - 椭圆 /// /// /// public void BinaryConnectionOval(RectangleF rect) { List choiseList = this.phaseModels.FindAll(a => a.choise == true); if (this.phaseModels != null && this.phaseModels.Count > 0 && choiseList.Count > 0) { foreach (PhaseModel p in choiseList) { p.mat = PreActionIntent.EllipseConnection(p.mat, p.color, rect, InvariantData.connection); this.panel.Refresh(); } } } /// /// 预处理 - 添加 - 椭圆 /// /// /// public void BinaryActionAddOval(RectangleF rect) { List choiseList = this.phaseModels.FindAll(a => a.choise == true); if (this.phaseModels != null && this.phaseModels.Count > 0 && choiseList.Count > 0) { foreach (PhaseModel p in choiseList) { p.mat = PreActionIntent.EllipseAdd(p.mat, p.color, rect); this.panel.Refresh(); } } } /// /// 预处理 - 添加 - 矩形 /// /// public void BinaryActionAddRectangle(RectangleF rect) { List choiseList = this.phaseModels.FindAll(a => a.choise == true); if (this.phaseModels != null && this.phaseModels.Count > 0 && choiseList.Count > 0) { foreach (PhaseModel p in choiseList) { p.mat = PreActionIntent.RectangleAdd(p.mat, p.color, rect); this.panel.Refresh(); } } } /// /// 预处理 - 交互操作 - 多边形添加 /// /// public void BinaryActionAddPolygon(List points) { if (points.Count > 2) { List choiseList = this.phaseModels.FindAll(a => a.choise == true); if (this.phaseModels != null && this.phaseModels.Count > 0 && choiseList.Count > 0) { foreach (PhaseModel p in choiseList) { p.mat = PreActionIntent.PolygonAdd(p.mat, p.color, points); this.panel.Refresh(); } } } } /// /// 预处理 - 交互操作 - 椭圆分割 /// /// public void BinaryActionSplitOval(RectangleF rect) { List choiseList = this.phaseModels.FindAll(a => a.choise == true); if (this.phaseModels != null && this.phaseModels.Count > 0 && choiseList.Count > 0) { foreach (PhaseModel p in choiseList) { p.mat = PreActionIntent.EllipseSplit(p.mat, rect, InvariantData.segmentation); this.panel.Refresh(); } } } #endregion #region 物相提取 public event EventHandler>> PPhaseActionFinish; private void OnPPhaseActionFinished(List mat) { if (PPhaseActionFinish != null) { PPhaseActionFinish(this, new EventArgs>(mat)); } } /// /// 物相提取 - 交互操作 - 矩形选择 /// /// public void PPhaseActionRectangle(RectangleF rect) { List objects = new List(); objects.Add(ContourParameters.Rectangle); objects.Add(rect); OnPPhaseActionFinished(objects); } /// /// 物相提取 - 交互操作 - 多边形选择 /// /// public void PPhaseActionPolygon(List points) { List objects = new List(); objects.Add(ContourParameters.Polygon); objects.Add(points); OnPPhaseActionFinished(objects); } /// /// 物相提取 - 交互操作 - 椭圆选择 /// /// public void PPhaseActionOval(RectangleF rect) { List objects = new List(); objects.Add(ContourParameters.Oval); objects.Add(rect); OnPPhaseActionFinished(objects); } #endregion #region 视场相关 /// /// 获取界面中的视场区域 /// /// public Region GetRegion() { Region a = null; if (this.GraphicsList != null && this.GraphicsList.Count > 0) { for (int i = this.GraphicsList.Count - 1; i >= 0; i--) { if (this.GraphicsList[i].objectType == DrawClass.View) { ViewBase view = (ViewBase)this.GraphicsList[i]; GraphicsPath path = new GraphicsPath(); switch (view.drawToolType) { case DrawToolType.ViewOval: case DrawToolType.ViewCircle: path.AddClosedCurve(view.Points.ToArray()); break; case DrawToolType.ViewRectangle: case DrawToolType.ViewSquare: case DrawToolType.ViewTriangle: case DrawToolType.ViewPolygon: case DrawToolType.ViewRectangleEx: case DrawToolType.ViewTriangleEx: if (view.GetPoints().Count > 2) { path.AddPolygon(view.GetPoints().ToArray()); } break; } if (a == null) { a = new Region(path); } else { if (view.combineMode == CombineMode.Union) a.Union(path); else a.Exclude(path); } } } } return a; } /// /// 剪切视场/透明剪切(通过颜色区分) /// /// 是否透明 /// public Bitmap GetCutSizeWithColorWhiteOrTransparentColor(bool transparent) { Region region = this.GetRegion(); Bitmap bitmap = this.CompositionSurface.CreateAliasedBitmap(); if (region != null) { //创建新图位图 Bitmap newBitmap = new Bitmap(bitmap.Width, bitmap.Height); //将新位图全部设置一个背景色 Graphics newGraphic = Graphics.FromImage(newBitmap); newGraphic.Clear(Color.FromArgb(0, 0, 0, 0)); //设置新位图绘制区域 newGraphic.Clip = region; //绘制白色背景色 newGraphic.Clear(Color.FromArgb(255, 255, 255, 255)); return newBitmap; } return bitmap; } /// /// 剪切视场/透明剪切 /// /// 是否透明 /// public Bitmap GetCutSizeWithColorWhiteOrTransparent(bool transparent) { Region region = this.GetRegion(); if (region != null) { //获取当前激活的图片 Bitmap bitmap = this.CompositionSurface.CreateAliasedBitmap(); //创建同样大小的新位图 Bitmap newBitmap = new Bitmap((int)(bitmap.Width), (int)(bitmap.Height)); //创建作图区域 Graphics newGraphic = Graphics.FromImage(newBitmap); //如果不是透明,则用白色填充 if (!transparent) newGraphic.Clear(Color.White); //设置新位图绘制区域 newGraphic.Clip = region; //截取原图相应区域写入作图区 newGraphic.DrawImage(bitmap, 0, 0, new RectangleF(0, 0, bitmap.Width, bitmap.Height), GraphicsUnit.Pixel); //创建region的RectangleF大小的位图 Graphics graphic = Graphics.FromImage(bitmap); RectangleF rectangleF = region.GetBounds(graphic); Bitmap lastBitmap = new Bitmap((int)(rectangleF.Width), (int)(rectangleF.Height)); Graphics lastGraphic = Graphics.FromImage(lastBitmap); lastGraphic.DrawImage(newBitmap, 0, 0, region.GetBounds(graphic), GraphicsUnit.Pixel); return lastBitmap; } return null; } /// /// 获取原图大小的Bitmap /// 除了视场外的其余均为透明(但保留各通道像素值), /// 主要是用于二值提取、物相提取等和视场关联的地方 /// /// public Bitmap GetFullSizeWithRegion(Bitmap bitmap = null) { Region region = this.GetRegion(); if (region != null) { if (bitmap == null) bitmap = this.CompositionSurface.CreateAliasedBitmap(); //创建同样的像素值的新位图,不过是透明的 Bitmap newBitmap = BaseTools.BitmapToTransparent(bitmap); //创建作图区域 Graphics newGraphic = Graphics.FromImage(newBitmap); //设置新位图绘制区域 newGraphic.Clip = region; //截取原图相应区域写入作图区 newGraphic.DrawImage(bitmap, 0, 0, new RectangleF(0, 0, bitmap.Width, bitmap.Height), GraphicsUnit.Pixel); return newBitmap; } return null; } #endregion #region 初始化控件 private void InitializeComponent() { this.components = new System.ComponentModel.Container(); this.contextMenuStrip1 = new System.Windows.Forms.ContextMenuStrip(this.components); this.toolStripMenuItem1 = new System.Windows.Forms.ToolStripMenuItem(); this.toolStripMenuItem2 = new System.Windows.Forms.ToolStripMenuItem(); this.toolStripMenuItem3 = new System.Windows.Forms.ToolStripMenuItem(); this.toolStripMenuItem4 = new System.Windows.Forms.ToolStripMenuItem(); this.panel = new PaintDotNet.PanelEx(); this.leftRuler = new PaintDotNet.RulerPro(); this.topRuler = new PaintDotNet.RulerPro(); this.contextMenuStrip1.SuspendLayout(); this.SuspendLayout(); // // contextMenuStrip1 // this.contextMenuStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { this.toolStripMenuItem1, this.toolStripMenuItem2, this.toolStripMenuItem3, this.toolStripMenuItem4}); this.contextMenuStrip1.Name = "contextMenuStrip1"; this.contextMenuStrip1.Size = new System.Drawing.Size(168, 92); // // toolStripMenuItem1 // this.toolStripMenuItem1.Name = "toolStripMenuItem1"; this.toolStripMenuItem1.Size = new System.Drawing.Size(167, 22); this.toolStripMenuItem1.Text = "MeasureSetting"; this.toolStripMenuItem1.Visible = false; this.toolStripMenuItem1.Click += new System.EventHandler(this.ToolStripMenuItem1_Click); // // toolStripMenuItem2 // this.toolStripMenuItem2.Name = "toolStripMenuItem2"; this.toolStripMenuItem2.Size = new System.Drawing.Size(167, 22); this.toolStripMenuItem2.Text = "LabelSetting"; this.toolStripMenuItem2.Visible = false; this.toolStripMenuItem2.Click += new System.EventHandler(this.ToolStripMenuItem2_Click); // // toolStripMenuItem3 // this.toolStripMenuItem3.Name = "toolStripMenuItem3"; this.toolStripMenuItem3.Size = new System.Drawing.Size(167, 22); this.toolStripMenuItem3.Text = "3celaing"; this.toolStripMenuItem3.Visible = false; this.toolStripMenuItem3.Click += new System.EventHandler(this.ToolStripMenuItem3_Click); // // toolStripMenuItem4 // this.toolStripMenuItem4.Name = "toolStripMenuItem4"; this.toolStripMenuItem4.Size = new System.Drawing.Size(167, 22); this.toolStripMenuItem4.Text = "biaozhushuxing"; this.toolStripMenuItem4.Visible = false; this.toolStripMenuItem4.Click += new System.EventHandler(this.ToolStripMenuItem4_Click); // // panel // this.panel.BackgroundImageLayout = System.Windows.Forms.ImageLayout.None; this.panel.ContextMenuStrip = this.contextMenuStrip1; this.panel.Dock = System.Windows.Forms.DockStyle.Fill; this.panel.HideHScroll = false; this.panel.HideVScroll = false; this.panel.IgnoreSetFocus = false; this.panel.Location = new System.Drawing.Point(20, 20); this.panel.Name = "panel"; this.panel.ScrollPosition = new System.Drawing.Point(0, 0); this.panel.Size = new System.Drawing.Size(364, 300); this.panel.TabIndex = 5; this.panel.KeyUp += new System.Windows.Forms.KeyEventHandler(this.Panel_KeyUp); this.panel.KeyDown += new System.Windows.Forms.KeyEventHandler(this.Panel_KeyDown); this.panel.KeyPress += new System.Windows.Forms.KeyPressEventHandler(this.Panel_KeyPress); this.panel.Scroll += new System.Windows.Forms.ScrollEventHandler(this.Panel_Scroll); this.panel.GotFocus += new System.EventHandler(this.Panel_GotFocus); this.panel.LostFocus += new System.EventHandler(this.Panel_LostFocus); // // leftRuler // this.leftRuler.BackColor = System.Drawing.Color.White; this.leftRuler.Dock = System.Windows.Forms.DockStyle.Left; this.leftRuler.HighlightLength = 2448F; this.leftRuler.HighlightStart = 2048F; this.leftRuler.Location = new System.Drawing.Point(0, 20); this.leftRuler.MeasurementUnit = PaintDotNet.MeasurementUnit.Micron; this.leftRuler.Name = "leftRuler"; this.leftRuler.Offset = 0F; this.leftRuler.Orientation = System.Windows.Forms.Orientation.Vertical; this.leftRuler.Size = new System.Drawing.Size(20, 300); this.leftRuler.TabIndex = 4; this.leftRuler.Value = 0F; this.leftRuler.MouseDown += new System.Windows.Forms.MouseEventHandler(this.Ruler_MouseDown); this.leftRuler.MouseMove += new System.Windows.Forms.MouseEventHandler(this.leftRuler_MouseMove); // // topRuler // this.topRuler.BackColor = System.Drawing.Color.White; this.topRuler.Dock = System.Windows.Forms.DockStyle.Top; this.topRuler.HighlightLength = 2448F; this.topRuler.HighlightStart = 2048F; this.topRuler.Location = new System.Drawing.Point(0, 0); this.topRuler.MeasurementUnit = PaintDotNet.MeasurementUnit.Micron; this.topRuler.Name = "topRuler"; this.topRuler.Offset = 0F; this.topRuler.Size = new System.Drawing.Size(384, 20); this.topRuler.TabIndex = 3; this.topRuler.Value = 0F; this.topRuler.MouseDown += new System.Windows.Forms.MouseEventHandler(this.Ruler_MouseDown); this.topRuler.MouseMove += new System.Windows.Forms.MouseEventHandler(this.topRuler_MouseMove); // // DocumentPreview // this.Controls.Add(this.panel); this.Controls.Add(this.leftRuler); this.Controls.Add(this.topRuler); this.Name = "DocumentPreview"; this.Size = new System.Drawing.Size(384, 320); this.contextMenuStrip1.ResumeLayout(false); this.ResumeLayout(false); } public void ShowContextMenuStrip1() { this.contextMenuStrip1.Visible = true; if (toolNumber == 0) { contextMenuStrip1.Visible = true; this.toolStripMenuItem1.Visible = true; this.toolStripMenuItem2.Visible = true; this.toolStripMenuItem3.Visible = false; this.toolStripMenuItem4.Visible = false; } else if (toolNumber == 1) { contextMenuStrip1.Visible = true; this.toolStripMenuItem1.Visible = false; this.toolStripMenuItem2.Visible = false; this.toolStripMenuItem3.Visible = true; this.toolStripMenuItem4.Visible = false; } else if (toolNumber == 2) { contextMenuStrip1.Visible = true; this.toolStripMenuItem1.Visible = false; this.toolStripMenuItem2.Visible = false; this.toolStripMenuItem3.Visible = false; this.toolStripMenuItem4.Visible = true; } else { contextMenuStrip1.Visible = false; this.toolStripMenuItem1.Visible = false; this.toolStripMenuItem2.Visible = false; this.toolStripMenuItem3.Visible = false; this.toolStripMenuItem4.Visible = false; } } #endregion #region 设定图片位置 // add by maxb 20200716 /// /// 图片位置坐标 /// private bool m_center = false; private double m_pTop => 20 + m_initTop * this.scaleFactor.Ratio + _rulerOffsetY; private double m_pLeft => 20 + _rulerOffsetX + m_initLeft * this.scaleFactor.Ratio; private int m_initTop = 0; private int m_initLeft = 0; public int ViewX { get => m_initTop; set { m_initLeft = value; topRuler.HighlightStart = value; if (m_center) { RulerOffsetX = scaleFactor.ScaleScalar(-value); } } } public int ViewY { get => m_initTop; set { m_initTop = value; leftRuler.HighlightStart = value; if (m_center) { RulerOffsetY = scaleFactor.ScaleScalar(-value); } } } public void SetViewPoint(int x, int y) { ViewX = x; ViewY = y; this.Refresh(); } public void SetCenter(bool center) { m_center = center; if (center) { RulerOffsetX = scaleFactor.ScaleScalar(-topRuler.HighlightStart); RulerOffsetY = scaleFactor.ScaleScalar(-leftRuler.HighlightStart); } } #endregion #region 工艺图比照 private RectangleF m_artworkImageRectangle; private Bitmap m_selectedBitmap; /// /// 工艺比照定位点图像绘制 /// /// /// public void SetSelectedBitmap(Bitmap bitmap, RectangleF rectangle) { m_selectedBitmap = bitmap; m_artworkImageRectangle = Rectangle.Ceiling(rectangle); this.Refresh(); } /// /// 工艺比照定位点 /// /// /// public void CreateArtworkRectangle(int id, Pen pen, Rectangle rect) { tools[(int)activeTool].InvokeMember("CreateRectangle", BindingFlags.Public | BindingFlags.Static | BindingFlags.InvokeMethod, null, null, new object[4] { this, id, pen, rect }); } #endregion #region 图像拼接 /// /// 生成自定义拼图区域 /// /// /// public void CreateStitchingRectangle(int width, int height) { int x = (int)m_pLeft; int y = (int)m_pTop; tools[(int)activeTool].InvokeMember("CreateRectangle", BindingFlags.Public | BindingFlags.Static | BindingFlags.InvokeMethod, null, null, new object[5] { this, x, y, width, height });// } /// /// 获取对应标尺上的坐标点 /// /// /// public PointF GetRulerPointInPanel(PointF point) { return new PointF( (float)((point.X - 16) / this.scaleFactor.Ratio), (float)((point.Y - 16) / this.scaleFactor.Ratio) ); } public PointF ScalePointToRulerPoint(PointF point) { Point originPoint = GetCalcOriginPoint(); return new PointF( (float)((point.X * this.scaleFactor.Ratio + originPoint.X - 16) / this.scaleFactor.Ratio), (float)((point.Y * this.scaleFactor.Ratio + originPoint.Y - 16) / this.scaleFactor.Ratio) ); } /// /// 是否开启鼠标左键双击移动视场 /// public bool ViewMoveOnMouseLeftDoubleClickEnable { get; set; } #endregion #region 位置列表 /// /// 生成自定义拼图区域 /// /// /// public void CreateLocationCross(int x, int y, int width, int height, int z) { //m_pLeft = x; //m_pTop = y; x = (int)(m_pLeft + x * this.scaleFactor.Ratio); y = (int)(m_pTop + y * this.scaleFactor.Ratio); ToolLocationCross.CreateLocationCross(this, x, y, width, height, z);// } #endregion #region 右键属性 /// /// 判断右键的工具 /// public int ToolNumber { set { this.toolNumber = value; } } /// /// 设置右键菜单的选项 /// /// /// private void ContextMenuStrip1_Opening(object sender, CancelEventArgs e) { if (toolNumber == 0) { contextMenuStrip1.Visible = true; this.toolStripMenuItem1.Visible = true; this.toolStripMenuItem2.Visible = true; this.toolStripMenuItem3.Visible = false; this.toolStripMenuItem4.Visible = false; } else if (toolNumber == 1) { contextMenuStrip1.Visible = true; this.toolStripMenuItem1.Visible = false; this.toolStripMenuItem2.Visible = false; this.toolStripMenuItem3.Visible = true; this.toolStripMenuItem4.Visible = false; } else if (toolNumber == 2) { contextMenuStrip1.Visible = true; this.toolStripMenuItem1.Visible = false; this.toolStripMenuItem2.Visible = false; this.toolStripMenuItem3.Visible = false; this.toolStripMenuItem4.Visible = true; } else { contextMenuStrip1.Visible = false; this.toolStripMenuItem1.Visible = false; this.toolStripMenuItem2.Visible = false; this.toolStripMenuItem3.Visible = false; this.toolStripMenuItem4.Visible = false; } } /// /// 右键菜单(测量设置) /// /// /// public virtual void ToolStripMenuItem1_Click(object sender, EventArgs e) { } /// /// 右键菜单(标注设置) /// /// /// public virtual void ToolStripMenuItem2_Click(object sender, EventArgs e) { } /// /// 右键菜单(测量属性) /// /// /// public virtual void ToolStripMenuItem3_Click(object sender, EventArgs e) { } /// /// 右键菜单(标注属性) /// /// /// public virtual void ToolStripMenuItem4_Click(object sender, EventArgs e) { } #endregion #region 对应图片保存的xml参数 public bool existenceXML = false;//当前图片是否存在对应的xml public mic_rulers xmlSaveModel;//存储标尺信息(xml或者预览拍摄选中标尺) /// /// 换算完的标尺信息,包含所有系统内得单位 /// public Dictionary rules = new Dictionary(); ///// ///// 系统内选定的单位 ///// //public MeasurementUnit measurementUnit; public mic_rulers RuleAttribute(PicConfigModel PicConfigModel) { this.xmlSaveModel = new mic_rulers(); //this.xmlSaveModel.rule = new XmlSaveModel.Rule(); this.xmlSaveModel.ruler_name = PicConfigModel.rule.ruler_name; this.xmlSaveModel.gain_multiple = PicConfigModel.rule.gain_multiple; this.xmlSaveModel.pixel_length = PicConfigModel.rule.pixel_length; this.xmlSaveModel.physical_length = PicConfigModel.rule.physical_length; this.xmlSaveModel.ruler_units = PicConfigModel.rule.ruler_units; InitRulerInfo(); this.existenceXML = true; return this.xmlSaveModel; } //显微镜硬件参数MODEL public Hardware hardware; public void HardwareAttribute() { this.hardware = new Hardware(); } public decimal GetMic_Rulers() { if (this.xmlSaveModel != null) { return this.xmlSaveModel.gain_multiple; } else { return appWorkspace.GetGainMultiple(); } } /// /// 初始化标尺信息,图片对应的xml中读取 /// 然后根据标尺的单位,换算出所有单位的数据 /// public void InitRulerInfo() { this.rules.Clear(); if (this.xmlSaveModel != null && this.xmlSaveModel.pixel_length != 0) { //计算单位长度 比如0.05英寸/像素; 100纳米/像素; double unitLength = (double)(this.xmlSaveModel.physical_length / (decimal)this.xmlSaveModel.pixel_length); switch (this.xmlSaveModel.ruler_units) { case (int)MeasurementUnit.Inch://英寸 this.rules.Add(MeasurementUnit.Inch, unitLength); //英寸 this.rules.Add(MeasurementUnit.Centimeter, 2.54 * unitLength); //厘米 this.rules.Add(MeasurementUnit.Millimeter, 25.4 * unitLength); //毫米 this.rules.Add(MeasurementUnit.Micron, 25400 * unitLength); //微米 this.rules.Add(MeasurementUnit.Nano, 25400000 * unitLength); //纳米 break; case (int)MeasurementUnit.Centimeter://厘米 this.rules.Add(MeasurementUnit.Inch, 0.3937008 * unitLength); //英寸 this.rules.Add(MeasurementUnit.Centimeter, unitLength); //厘米 this.rules.Add(MeasurementUnit.Millimeter, 10 * unitLength); //毫米 this.rules.Add(MeasurementUnit.Micron, 10000 * unitLength); //微米 this.rules.Add(MeasurementUnit.Nano, 10000000 * unitLength); //纳米 break; case (int)MeasurementUnit.Millimeter://毫米 this.rules.Add(MeasurementUnit.Inch, 0.0393701 * unitLength); //英寸 this.rules.Add(MeasurementUnit.Centimeter, 0.1 * unitLength); //厘米 this.rules.Add(MeasurementUnit.Millimeter, unitLength); //毫米 this.rules.Add(MeasurementUnit.Micron, 1000 * unitLength); //微米 this.rules.Add(MeasurementUnit.Nano, 1000000 * unitLength); //纳米 break; case (int)MeasurementUnit.Micron://微米 this.rules.Add(MeasurementUnit.Inch, 0.00003937007874 * unitLength); //英寸 this.rules.Add(MeasurementUnit.Centimeter, 0.0001 * unitLength); //厘米 this.rules.Add(MeasurementUnit.Millimeter, 0.001 * unitLength); //毫米 this.rules.Add(MeasurementUnit.Micron, unitLength); //微米 this.rules.Add(MeasurementUnit.Nano, 1000 * unitLength); //纳米 break; case (int)MeasurementUnit.Nano://纳米 this.rules.Add(MeasurementUnit.Inch, 3.9370e-8 * unitLength); //英寸 this.rules.Add(MeasurementUnit.Centimeter, 1e-7 * unitLength); //厘米 this.rules.Add(MeasurementUnit.Millimeter, 1e-6 * unitLength); //毫米 this.rules.Add(MeasurementUnit.Micron, 0.001 * unitLength); //微米 this.rules.Add(MeasurementUnit.Nano, unitLength); //纳米 break; default: this.xmlSaveModel = null; break; } } if (this.xmlSaveModel == null || this.xmlSaveModel.physical_length == 0) { //如果没有标尺的时候,默认1微米/像素 this.rules.Add(MeasurementUnit.Inch, 0.0000394); //英寸 this.rules.Add(MeasurementUnit.Centimeter, 0.0001); //厘米 this.rules.Add(MeasurementUnit.Millimeter, 0.001); //毫米 this.rules.Add(MeasurementUnit.Micron, 1); //微米 this.rules.Add(MeasurementUnit.Nano, 1000); //纳米 this.xmlSaveModel = new mic_rulers(); this.xmlSaveModel.ruler_name = PdnResources.GetString("Menu.Unselectedruler.Text"); this.xmlSaveModel.gain_multiple = 1; this.xmlSaveModel.physical_length = 100; this.xmlSaveModel.pixel_length = 100; this.xmlSaveModel.ruler_units = (int)((MeasurementUnit)System.Enum.Parse(typeof(MeasurementUnit), this.getRulerList()[0])); } //设置文档标尺 Document.defaultDpi = 1 / rules[MeasurementUnit.Inch]; } /// /// 提供获取系统当前选中单位及每单位像素值公共方法 /// /// public string[] getRulerList() { return startUpRules(this.rules.Count > 0 ? this.rules : null); } #region 标尺拖拽 int _lastX = 0; int _lastY = 0; float _rulerOffsetX = 0; float _rulerOffsetY = 0; public float RulerOffsetX { get => _rulerOffsetX; set { DrawStithchingBase.OffsetX = ScaleFactor.UnscaleScalar((int)value); _rulerOffsetX = value;//> 0 ? 0 : value; UpdateRulerOffsets(); } } public float RulerOffsetY { get => _rulerOffsetY; set { DrawStithchingBase.OffsetY = ScaleFactor.UnscaleScalar((int)value ); _rulerOffsetY = value;// > 0 ? 0 : value; UpdateRulerOffsets(); } } private void UpdateRulerOffsets() { this.topRuler.Offset = ScaleFactor.UnscaleScalar(UI.ScaleWidth(-20) - _rulerOffsetX - this.panel.Location.X); topRuler.Update(); this.leftRuler.Offset = ScaleFactor.UnscaleScalar(UI.ScaleWidth(0) - _rulerOffsetY - this.panel.Location.Y); leftRuler.Update(); } private void topRuler_MouseMove(object sender, MouseEventArgs e) { if (!m_center && e.Button == MouseButtons.Left) { var len = e.X - _lastX; RulerOffsetX += len; _lastX = e.X; panel.Invalidate(); } } private void leftRuler_MouseMove(object sender, MouseEventArgs e) { if (!m_center && e.Button == MouseButtons.Left) { var len = e.Y - _lastY; RulerOffsetY += len; _lastY = e.Y; panel.Invalidate(); } } private void Ruler_MouseDown(object sender, MouseEventArgs e) { if (e.Button == MouseButtons.Left) { _lastX = e.X; _lastY = e.Y; } } #endregion /// /// 获取单位标尺 /// /// 度量单位的枚举 /// public double GetRuler(MeasurementUnit measurementUnit) { double unitLength = 0; //判断当前图片是否有对应的标尺 if (this.rules.Count > 0) { this.rules.TryGetValue(measurementUnit, out unitLength); } else { this.appWorkspace.getMeasureInfo().TryGetValue(MeasurementUnit.Micron, out unitLength); } return unitLength; } public void SetContinuousDrawingLabel(bool v) { } public void SetContinuousDrawingMeasure(bool v) { } #endregion public Type[] GetTools() { return this.tools; } public MeasurementUnit GetMeasurementUnit() { return this.Units; } } }