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; using PaintDotNet.Base.CommTool; using PaintDotNet.Base.DedicatedAnalysis.Inclusions.Model; 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.Runtime.InteropServices; using System.Threading; using System.Windows.Forms; using static PaintDotNet.Base.SettingModel.LabelStyleModel; namespace PaintDotNet { /// /// 主面板 /// public class DocumentView : UserControl2, ISurfaceBox, DocumentDirtyObserver { #region 控件 private IContainer components = null; /// /// 左侧刻度标尺 /// public Ruler leftRuler; /// /// 中心画布 /// public PanelEx panel; /// /// 顶部刻度标尺 /// public Ruler topRuler; /// /// 右键菜单 /// protected ContextMenuStrip contextMenuStrip1; protected ToolStripMenuItem toolStripMenuItem1; protected ToolStripMenuItem toolStripMenuItem2; protected ToolStripMenuItem toolStripMenuItem3; protected ToolStripMenuItem toolStripMenuItem4; #endregion /// /// 是否创建缩略图 /// public bool IsCreatThumb = true; private bool raiseFirstInputAfterGotFocus = false; private bool hookedMouseEvents = false; public static WeakReference doubleBufferSurfaceWeakRef = null; public Surface doubleBufferSurface = null; //private static WeakReference doubleBufferSurfaceWeakRef1 = null; //private Surface doubleBufferSurface1 = null; /// /// 清理DoubleBuffer /// public void ClearDoubleBuffer() { doubleBufferSurfaceWeakRef = null; doubleBufferSurface = null; } /// /// 绘制线程 /// private Threading.ThreadPool threadPool = new Threading.ThreadPool(); private RenderContext renderContext, renderContext_Phase; /// /// 为了保证图片绘制在画布中心 /// 设置的偏移量 /// private int offsetW = 0; private int offsetH = 0; private int offsetHalfW = 0; private int offsetHalfH = 0; /*private int offsetW = 300; private int offsetH = 150; private int offsetHalfW = 150; private int offsetHalfH = 75;*/ public TreeView oldDrawTreeView; /// /// 相的集合 /// 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; /// /// 测量连续绘制 /// public static bool ContinuousDrawing = 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; /// /// 图像内存块及其属性 /// protected Surface compositionSurface; /// /// 【标注、测量】用于保存测量、标注等的历史记录,用于撤销 /// public UndoManager undoManager; /// /// 【标注、测量】list of draw objects /// private GraphicsList graphicsList; /// /// 【标注、测量、视场、其它】当前激活的工具 /// public DrawToolType _activeTool; /// /// 工具的集合 /// protected static Dictionary tools; /// /// 初始化标记 /// private bool initialized; /// /// AppWorkspace接口 /// private IAppWorkspaceForSurfaceBox appWorkspace; /// /// 目前用于修改视场,如果是鼠标保持按下的状态,比如按下不抬起状态, /// 按下拖动状态,则不响应修改视场界面的相应numericUpDown等控件的值变化事件, /// 以避免事件的冲突 /// public bool mouseStatus; /// /// 辅助线的横线和竖线 /// GraphicsPath path, path1; /// /// 待渲染的列表 /// private SurfaceBoxRendererList rendererList; private SurfaceBoxBaseRenderer baseRenderer; /// /// 窗体状态 /// private FormWindowState oldWindowState = FormWindowState.Minimized; /// /// 缩放比例 /// private ScaleFactor scaleFactor = new ScaleFactor(1, 1); /// /// 每像素多少微米 /// private double micronRatio; /// /// 是否允许像素跟踪 /// public bool pixelTrackingEnabled = true; /// /// 是否允许刷新公共的底部的放大缩小的进度条和值 /// public bool refueshZoomTrackValue = true; protected 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; public Inclusion inclusion; #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; #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 DocumentView() { 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.rendererList = new SurfaceBoxRendererList(this.panel.Size, this.panel.Size); this.rendererList.Invalidated += new InvalidateEventHandler(Renderers_Invalidated); this.baseRenderer = new SurfaceBoxBaseRenderer(this.rendererList, null); this.rendererList.Add(this.baseRenderer, false); //phaseModels.ListChanged += new ListChangedEventHandler(this.phaseModels_Change); this.initialized = true; } public unsafe void phaseModels_Change(object sender) { this.rendererList.topList = new SurfaceBoxRenderer[0]; foreach (PhaseModel model in phaseModels) { Surface surface1 = null; if (model.mat != null) { surface1 = new Surface(model.mat.Width, model.mat.Height); surface1.mat = model.mat.Clone(); surface1.scan0.VoidStar = (void*)model.mat.Data; surface1.Stride = (int)model.mat.Step(); } this.rendererList.Add(new SurfaceBoxBaseRenderer(this.rendererList, surface1), true); } } public new void Refresh() { this.phaseModels_Change(null); base.Refresh(); } public OpenCvSharp.Mat OldMat { get { if (this.CompositionSurface != null && CompositionSurface != null && CompositionSurface.mat != null) return this.CompositionSurface.BackUpMat; else return null; } } public OpenCvSharp.Mat BoxMat { get { if(this.CompositionSurface.Width>10000 || this.CompositionSurface.Height>10000) { OpenCvSharp.Mat temp = new OpenCvSharp.Mat(); int width = this.CompositionSurface.Width / 10; int height = this.CompositionSurface.Height / 10; OpenCvSharp.Cv2.Resize(this.CompositionSurface.BackUpMat, temp, new OpenCvSharp.Size(width==0 ? 1 : width, height==0?1:height)); return temp; } else { return this.CompositionSurface.BackUpMat; } } } 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 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 ContinuousDrawing; } set { ContinuousDrawing = value; } } public bool ContinuousDrawingMeasure { get { return ContinuousDrawing; } set { ContinuousDrawing = 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; } } public SurfaceBoxRendererList RendererList { get { return this.rendererList; } } /// /// 初始化工具 /// protected void InitToolsAndManager() { // 一是用于存储,二是用于调整层级 GraphicsList = new GraphicsList(this); // 创建管理器,用于前进后退 undoManager = new UndoManager(GraphicsList); // init Tools //tools = new Tool[(int)DrawToolType.NumberOfDrawTools]; if (tools != null) return; tools = new Dictionary(); tools.Add(DrawToolType.Pointer, typeof(ToolPointer)); // //标注 // tools.Add(DrawToolType.DrawRectangle, typeof(ToolRectangle)); tools.Add(DrawToolType.DrawEllipse, typeof(ToolEllipse)); tools.Add(DrawToolType.DrawLine, typeof(ToolLine)); tools.Add(DrawToolType.DrawPolygon, typeof(ToolPolygon)); tools.Add(DrawToolType.DrawPolygonLine, typeof(ToolPolygonLine)); tools.Add(DrawToolType.DrawPencil, typeof(ToolPencil)); tools.Add(DrawToolType.DrawClosedCurve, typeof(ToolClosedCurve)); tools.Add(DrawToolType.DrawCurve, typeof(ToolCurve)); tools.Add(DrawToolType.DrawCircle, typeof(ToolCircle)); tools.Add(DrawToolType.DrawOneArrowLine, typeof(ToolOneArrowLine)); tools.Add(DrawToolType.DrawTwoArrowLine, typeof(ToolTwoArrowLine)); tools.Add(DrawToolType.DrawLineSegment, typeof(ToolLineSegment)); tools.Add(DrawToolType.DrawRoundRectangle, typeof(ToolRoundRectangle)); tools.Add(DrawToolType.DrawTextString, typeof(ToolTextString)); tools.Add(DrawToolType.DrawDateMark, typeof(ToolDateMark)); tools.Add(DrawToolType.DrawTimeMark, typeof(ToolTimeMark)); tools.Add(DrawToolType.DrawNumberMark, typeof(ToolNumberMark)); tools.Add(DrawToolType.DrawGainNumber, typeof(ToolGainNumber)); tools.Add(DrawToolType.DrawWorkType, typeof(ToolWorkType)); tools.Add(DrawToolType.DrawPointMark, typeof(ToolPointMark)); tools.Add(DrawToolType.DrawWaterMark, typeof(ToolWaterMark)); //分析绘图 tools.Add(DrawToolType.DrawCircleA, typeof(ToolCircleA)); tools.Add(DrawToolType.DrawMulLineA, typeof(ToolDrawMulLineA)); // //测量 // tools.Add(DrawToolType.MeasureLine, typeof(ToolMeasureLine)); tools.Add(DrawToolType.MeasureDistanceLine, typeof(ToolMeasureDistanceLine)); tools.Add(DrawToolType.MeasureLength, typeof(ToolMeasureLength)); tools.Add(DrawToolType.MeasureTraceCurve, typeof(ToolMeasureTraceCurve)); tools.Add(DrawToolType.MeasureHLine, typeof(ToolMeasureHLine)); tools.Add(DrawToolType.MeasureVLine, typeof(ToolMeasureVLine)); tools.Add(DrawToolType.MeasureCircle, typeof(ToolMeasureCircle)); tools.Add(DrawToolType.MeasureInnerCircle, typeof(ToolMeasureInnerCircle)); tools.Add(DrawToolType.MeasureOuterCircle, typeof(ToolMeasureOuterCircle)); tools.Add(DrawToolType.MeasureDiameterCircle, typeof(ToolMeasureDiameterCircle)); tools.Add(DrawToolType.MeasurePointEdgeSize, typeof(ToolMeasurePointEdgeSize)); tools.Add(DrawToolType.MeasurePointCenterSize, typeof(ToolMeasurePointCenterSize)); tools.Add(DrawToolType.MeasureBrokenLine, typeof(ToolMeasureBrokenLine)); tools.Add(DrawToolType.MeasureCurveLine, typeof(ToolMeasureCurveLine)); tools.Add(DrawToolType.MeasureThreePointAngle, typeof(ToolMeasureThreePointAngle)); tools.Add(DrawToolType.MeasureFourPointAngle, typeof(ToolMeasureFourPointAngle)); tools.Add(DrawToolType.MeasureThreePointArc, typeof(ToolMeasureThreePointArc)); tools.Add(DrawToolType.MeasurePLine, typeof(ToolMeasurePLine)); tools.Add(DrawToolType.MeasureMulPLine, typeof(ToolMeasureMulPLine)); tools.Add(DrawToolType.MeasureHMulPLine, typeof(ToolMeasureHMulPLine)); tools.Add(DrawToolType.MeasureVMulPLine, typeof(ToolMeasureVMulPLine)); tools.Add(DrawToolType.MeasureParallelLine, typeof(ToolMeasureParallelLine)); tools.Add(DrawToolType.MeasureMulParallelLine, typeof(ToolMeasureMulParallelLine)); tools.Add(DrawToolType.MeasureVMulParallelLine, typeof(ToolMeasureVMulParallelLine)); tools.Add(DrawToolType.MeasureHMulParallelLine, typeof(ToolMeasureHMulParallelLine)); tools.Add(DrawToolType.MeasureClosedCurve, typeof(ToolMeasureClosedCurve)); tools.Add(DrawToolType.MeasurePolygon, typeof(ToolMeasurePolygon)); tools.Add(DrawToolType.MeasureRectangle, typeof(ToolMeasureRectangle)); tools.Add(DrawToolType.MeasureRandRectangle, typeof(ToolMeasureRandRectangle)); tools.Add(DrawToolType.MeasureSquare, typeof(ToolMeasureSquare)); tools.Add(DrawToolType.MeasureTracePolygon, typeof(ToolMeasureTracePolygon)); tools.Add(DrawToolType.MeasureMulLine, typeof(ToolMeasureMulLine)); tools.Add(DrawToolType.MeasureMulSegment, typeof(ToolMeasureMulSegment)); tools.Add(DrawToolType.MeasureMulHVLine, typeof(ToolMeasureMulHVLine)); tools.Add(DrawToolType.MeasureMulVLine, typeof(ToolMeasureMulVLine)); tools.Add(DrawToolType.MeasureRandSquare, typeof(ToolMeasureRandSquare)); tools.Add(DrawToolType.MeasurePointHLine, typeof(ToolMeasurePointHLine)); tools.Add(DrawToolType.MeasurePointArcSize, typeof(ToolMeasurePointArcSize)); tools.Add(DrawToolType.MeasureCenterCenterSize, typeof(ToolMeasureCenterCenterSize)); tools.Add(DrawToolType.MeasureTwoLineVLDistance, typeof(ToolMeasureTwoLineVLDistance)); // //视场 // tools.Add(DrawToolType.ViewOval, typeof(ToolViewOval)); tools.Add(DrawToolType.ViewCircle, typeof(ToolViewCircle)); tools.Add(DrawToolType.ViewRectangle, typeof(ToolViewRectangle)); tools.Add(DrawToolType.ViewRectangleEx, typeof(ToolViewRectangleEx)); tools.Add(DrawToolType.ViewTriangle, typeof(ToolViewTriangle)); tools.Add(DrawToolType.ViewTriangleEx, typeof(ToolViewTriangleEx)); tools.Add(DrawToolType.ViewSquare, typeof(ToolViewSquare)); tools.Add(DrawToolType.ViewPolygon, typeof(ToolViewPolygon)); #region 对象处理 //单个提取 tools.Add(DrawToolType.BinaryExtract, typeof(ToolBinaryExtract)); //选择 tools.Add(DrawToolType.BinaryChoise, typeof(ToolBinaryChoise)); tools.Add(DrawToolType.BinaryChoiseRectangle, typeof(ToolBinaryChoiseRectangle)); tools.Add(DrawToolType.BinaryChoiseOval, typeof(ToolBinaryChoiseOval)); tools.Add(DrawToolType.BinaryChoisePolygon, typeof(ToolBinaryChoisePolygon)); //添加 tools.Add(DrawToolType.BinaryAddOval, typeof(ToolBinaryAddOval)); tools.Add(DrawToolType.BinaryAddRectangle, typeof(ToolBinaryAddRectangle)); tools.Add(DrawToolType.BinaryAddPolygon, typeof(ToolBinaryAddPolygon)); tools.Add(DrawToolType.BinaryAddTrack, typeof(ToolBinaryAddTrack)); //删除 tools.Add(DrawToolType.BinaryDelete, typeof(ToolBinaryDelete)); tools.Add(DrawToolType.BinaryDeleteRectangle, typeof(ToolBinaryDeleteRectangle)); tools.Add(DrawToolType.BinaryDeletePolygon, typeof(ToolBinaryDeletePolygon)); tools.Add(DrawToolType.BinaryDeleteOval, typeof(ToolBinaryDeleteOval)); //连接 tools.Add(DrawToolType.BinaryConnectionLine, typeof(ToolBinaryConnectionLine)); tools.Add(DrawToolType.BinaryConnectionPolygonLine, typeof(ToolBinaryConnectionPolygonLine)); tools.Add(DrawToolType.BinaryConnectionOval, typeof(ToolBinaryConnectionOval)); //分割 tools.Add(DrawToolType.BinarySplitLine, typeof(ToolBinarySplitLine)); tools.Add(DrawToolType.BinarySplitPolyline, typeof(ToolBinarySplitPolyLine)); tools.Add(DrawToolType.BinarySplitOval, typeof(ToolBinarySplitOval)); #endregion #region 专用分析 // 夹杂物 tools.Add(DrawToolType.InclusionNoEffect, typeof(ToolInclusionNoEffect)); tools.Add(DrawToolType.InclusionSelect, typeof(ToolInclusionSelect)); tools.Add(DrawToolType.InclusionPolygon, typeof(ToolInclusionPolygon)); tools.Add(DrawToolType.InclusionNewPolygon, typeof(ToolInclusionNewPolygon)); tools.Add(DrawToolType.InclusionDrawRecognitionArea, typeof(ToolInclusionDrawRecognitionArea)); tools.Add(DrawToolType.InclusionSelectRecognitionArea, typeof(ToolInclusionSelectRecognitionArea)); #endregion #region 物相提取 //多边形 tools.Add(DrawToolType.PPhasePolygon, typeof(ToolPPhasePolygon)); //矩形 tools.Add(DrawToolType.PPhaseRectangle, typeof(ToolPPhaseRectangle)); //椭圆 tools.Add(DrawToolType.PPhaseOval, typeof(ToolPPhaseOval)); #endregion //其它 //手型工具 tools.Add(DrawToolType.MoveMode, typeof(PanTool)); //图片裁剪 tools.Add(DrawToolType.ImageCut, typeof(ImageCutTool)); //自动标尺 tools.Add(DrawToolType.DrawAutoRuler, typeof(ToolAutoRuler)); //预存标尺 tools.Add(DrawToolType.DrawPrestoredRuler, typeof(ToolPrestoredRuler)); //手动标尺 tools.Add(DrawToolType.DrawHandModeRuler, typeof(ToolHandModeRuler)); //光密度直线绘制 tools.Add(DrawToolType.OpticalDensityLine, typeof(ToolOpticalDensityLine)); //划痕处理 tools.Add(DrawToolType.DrawScratchTreatmentLine, typeof(ToolScratchTreatmentLine)); //污迹处理-矩形 tools.Add(DrawToolType.DrawSmudgeRectangle, typeof(ToolSmudgeRectangle)); //污迹处理-多边形 tools.Add(DrawToolType.DrawSmudgePolygon, typeof(ToolSmudgePolygon)); //污迹处理-圆形 tools.Add(DrawToolType.DrawSmudgeCircle, typeof(ToolSmudgeCircle)); //污迹处理-椭圆 tools.Add(DrawToolType.DrawSmudgeEllipse, typeof(ToolSmudgeEllipse)); //吸管工具 tools.Add(DrawToolType.ColorPicker, typeof(ColorPickerTool)); //null tools.Add(DrawToolType.NullTool, typeof(ToolNull)); // 图像拼接-矩形 tools.Add(DrawToolType.DrawStitchingRectangle, typeof(ToolStitchingRectangle)); // 图像拼接-圆形 tools.Add(DrawToolType.DrawStitchingCircle, typeof(ToolStitchingCircle)); // 图像拼接-多边形 tools.Add(DrawToolType.DrawStitchingPolygon, typeof(ToolStitchingPolygon)); // 工艺图对照点矩形 tools.Add(DrawToolType.DrawArtworkRectangle, typeof(ToolArtworkRectangle)); // 位置列表十字线 tools.Add(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[] { }; } public bool DrawGrid { get { return false;// this.gridRenderer.Visible; } set { /** if (this.gridRenderer.Visible != value) { this.gridRenderer.Visible = value; OnDrawGridChanged(); }**/ } } /// /// 获取标尺集合 /// /// protected virtual List Mic_rulersAll() { return new List(); } [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); } public Surface GetDoubleBuffer(Size size) { Surface localDBSurface = null; Size oldSize = new Size(0, 0); // If we already have a double buffer surface reference, but if that surface // is already disposed then don't worry about it. if (this.doubleBufferSurface != null && this.doubleBufferSurface.IsDisposed) { oldSize = this.doubleBufferSurface.Size; this.doubleBufferSurface = null; } // If we already have a double buffer surface reference, but if that surface // is too small, then nuke it. if (this.doubleBufferSurface != null && (this.doubleBufferSurface.Width < size.Width || this.doubleBufferSurface.Height < size.Height)) { oldSize = this.doubleBufferSurface.Size; this.doubleBufferSurface.Dispose(); this.doubleBufferSurface = null; doubleBufferSurfaceWeakRef = null; } // If we don't have a double buffer, then we'd better get one. if (this.doubleBufferSurface != null) { // Got one! localDBSurface = this.doubleBufferSurface; } else if (doubleBufferSurfaceWeakRef != null) { // First, try to get the one that's already shared amongst all SurfaceBox instances. localDBSurface = doubleBufferSurfaceWeakRef.Target; // If it's disposed, then forget about it. if (localDBSurface != null && localDBSurface.IsDisposed) { oldSize = localDBSurface.Size; localDBSurface = null; doubleBufferSurfaceWeakRef = null; } } // Make sure the surface is big enough. if (localDBSurface != null && (localDBSurface.Width < size.Width || localDBSurface.Height < size.Height)) { oldSize = localDBSurface.Size; localDBSurface.Dispose(); localDBSurface = null; doubleBufferSurfaceWeakRef = null; } // So, do we have a surface? If not then we'd better make one. if (localDBSurface == null) { Size newSize = new Size(Math.Max(size.Width, oldSize.Width), Math.Max(size.Height, oldSize.Height)); localDBSurface = new Surface(newSize.Width, newSize.Height); doubleBufferSurfaceWeakRef = new WeakReference(localDBSurface); } this.doubleBufferSurface = localDBSurface; Surface window = localDBSurface.CreateWindow(0, 0, size.Width, size.Height); return window; } /* public Surface GetDoubleBuffer1(Size size) { Surface localDBSurface = null; Size oldSize = new Size(0, 0); // If we already have a double buffer surface reference, but if that surface // is already disposed then don't worry about it. if (this.doubleBufferSurface1 != null && this.doubleBufferSurface1.IsDisposed) { oldSize = this.doubleBufferSurface1.Size; this.doubleBufferSurface1 = null; } // If we already have a double buffer surface reference, but if that surface // is too small, then nuke it. if (this.doubleBufferSurface1 != null && (this.doubleBufferSurface1.Width < size.Width || this.doubleBufferSurface1.Height < size.Height)) { oldSize = this.doubleBufferSurface1.Size; this.doubleBufferSurface1.Dispose(); this.doubleBufferSurface1 = null; doubleBufferSurfaceWeakRef1 = null; } // If we don't have a double buffer, then we'd better get one. if (this.doubleBufferSurface1 != null) { // Got one! localDBSurface = this.doubleBufferSurface1; } else if (doubleBufferSurfaceWeakRef1 != null) { // First, try to get the one that's already shared amongst all SurfaceBox instances. localDBSurface = doubleBufferSurfaceWeakRef1.Target; // If it's disposed, then forget about it. if (localDBSurface != null && localDBSurface.IsDisposed) { oldSize = localDBSurface.Size; localDBSurface = null; doubleBufferSurfaceWeakRef1 = null; } } // Make sure the surface is big enough. if (localDBSurface != null && (localDBSurface.Width < size.Width || localDBSurface.Height < size.Height)) { oldSize = localDBSurface.Size; localDBSurface.Dispose(); localDBSurface = null; doubleBufferSurfaceWeakRef1 = null; } // So, do we have a surface? If not then we'd better make one. if (localDBSurface == null) { Size newSize = new Size(Math.Max(size.Width, oldSize.Width), Math.Max(size.Height, oldSize.Height)); localDBSurface = new Surface(newSize.Width, newSize.Height); doubleBufferSurfaceWeakRef1 = new WeakReference(localDBSurface); } this.doubleBufferSurface1 = localDBSurface; Surface window = localDBSurface.CreateWindow(0, 0, size.Width, size.Height); return window; } */ private class RenderContext { public Surface[] windows; public Point[] offsets; public Rectangle[] rects; public DocumentView owner; public WaitCallback waitCallback; public int TopIndex = 0; public void RenderThreadMethod1(object indexObject) { int index = (int)indexObject; this.owner.rendererList.topList[TopIndex].Render(windows[index], offsets[index]); //this.owner.rendererList.RenderTop(windows[index], offsets[index]); this.windows[index].Dispose(); this.windows[index] = null; } public void RenderThreadMethod(object indexObject) { int index = (int)indexObject; this.owner.rendererList.list[0].Render(windows[index], offsets[index]); this.windows[index].Dispose(); this.windows[index] = null; } } public unsafe void DrawArea(RenderArgs ra, Point offset) { if (compositionSurface == null) { return; } if (renderContext == null || (renderContext.windows != null && renderContext.windows.Length != Processor.LogicalCpuCount)) { renderContext = new RenderContext(); //这里需要计算宽高 renderContext.owner = this; renderContext.waitCallback = new WaitCallback(renderContext.RenderThreadMethod); renderContext.windows = new Surface[Processor.LogicalCpuCount]; renderContext.offsets = new Point[Processor.LogicalCpuCount]; renderContext.rects = new Rectangle[Processor.LogicalCpuCount]; } Utility.SplitRectangle(ra.Bounds, renderContext.rects); for (int i = 0; i < renderContext.rects.Length; ++i) { if (renderContext.rects[i].Width > 0 && renderContext.rects[i].Height > 0) { renderContext.offsets[i] = new Point(renderContext.rects[i].X + offset.X, renderContext.rects[i].Y + offset.Y); renderContext.windows[i] = ra.Surface.CreateWindow(renderContext.rects[i]); } else { renderContext.windows[i] = null; } } for (int i = 0; i < renderContext.windows.Length; ++i) { if (renderContext.windows[i] != null) { this.threadPool.QueueUserWorkItem(renderContext.waitCallback, BoxedConstants.GetInt32(i)); } } try { this.threadPool.Drain(); } catch { } } public unsafe void DrawArea1(RenderArgs ra, Point offset, int TopIndex) { if (compositionSurface == null) { return; } if (renderContext_Phase == null || (renderContext_Phase.windows != null && renderContext_Phase.windows.Length != Processor.LogicalCpuCount)) { renderContext_Phase = new RenderContext(); //这里需要计算宽高 renderContext_Phase.owner = this; renderContext_Phase.waitCallback = new WaitCallback(renderContext_Phase.RenderThreadMethod1); renderContext_Phase.windows = new Surface[1];//Processor.LogicalCpuCount renderContext_Phase.offsets = new Point[1]; renderContext_Phase.rects = new Rectangle[1]; } renderContext_Phase.TopIndex = TopIndex; Utility.SplitRectangle(ra.Bounds, renderContext_Phase.rects); for (int i = 0; i < renderContext_Phase.rects.Length; ++i) { if (renderContext_Phase.rects[i].Width > 0 && renderContext_Phase.rects[i].Height > 0) { renderContext_Phase.offsets[i] = new Point(renderContext_Phase.rects[i].X + offset.X, renderContext_Phase.rects[i].Y + offset.Y); renderContext_Phase.windows[i] = ra.Surface.CreateWindow(renderContext_Phase.rects[i]); } else { renderContext_Phase.windows[i] = null; } } for (int i = 0; i < renderContext_Phase.windows.Length; ++i) { if (renderContext_Phase.windows[i] != null) { this.threadPool.QueueUserWorkItem(renderContext_Phase.waitCallback, BoxedConstants.GetInt32(i)); } } try { this.threadPool.Drain(); } catch { } } protected override void OnLoad(EventArgs e) { base.OnLoad(e); // Sometimes OnLoad() gets called *twice* for some reason. // See bug #1415 for the symptoms. /**if (!this.hookedMouseEvents) { this.hookedMouseEvents = true; foreach (Control c in Controls) { HookMouseEvents(c); } }**/ 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.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(); } } public override bool IsMouseCaptured() { return panel.Capture || leftRuler.Capture || topRuler.Capture;//this.Capture || } /// /// 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); } } /// /// 合适大小 /// 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; // 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.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); //////求因缩放产生的位移,进行补偿,实现锚点缩放的效果 ////VX = (int)((double)x * (ow - pictureBox1.Width) / ow); ////VY = (int)((double)y * (oh - pictureBox1.Height) / oh); ////pictureBox1.Location = new Point(pictureBox1.Location.X + VX, pictureBox1.Location.Y + VY); //this.panel.AutoScrollPosition = new Point((int)(width - rc.Width) / 2 + 150, (int)(height - rc.Height) / 2 + 75); //////this.panel.AutoScrollPosition = sbClient; ////UpdateRulerOffsets(); ////this.topRuler.Invalidate(); ////this.leftRuler.Invalidate(); } else { this.panel.AutoScrollMinSize = new Size((int)(this.compositionSurface.Width * scaleFactor.Ratio), (int)(this.compositionSurface.Height * scaleFactor.Ratio)); //this.panel.AutoScrollPosition = new Point((int)(width - rc.Width) / 2 + 0, (int)(height - rc.Height) / 2 + 0); ////UpdateRulerOffsets(); ////this.topRuler.Invalidate(); ////this.leftRuler.Invalidate(); } 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(); */ if (compositionSurface != null) this.rendererList.DestinationSize = this.scaleFactor.ScaleSize(compositionSurface.Size); UI.ResumeControlPainting(this); Invalidate(true); } } /// /// 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 (rectF.Width == 0 || rectF.Height == 0) { this.leftRuler.HighlightEnabled = false; this.topRuler.HighlightEnabled = false; } else { if (this.topRuler != null) { this.topRuler.HighlightEnabled = true; this.topRuler.HighlightStart = rectF.Left; this.topRuler.HighlightLength = rectF.Width; } if (this.leftRuler != null) { this.leftRuler.HighlightEnabled = true; 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 { if (InvokeRequired) { this.Invoke(new Procedure(DocumentSetImpl), new object[2] { value, true }); } else { DocumentSetImpl(value, true); } } } 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); 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 (!toedit && this.compositionSurface.Thumborigin != null) // document.surface.Thumborigin = OpenCvSharp.Extensions.BitmapConverter.ToBitmap(OpenCvSharp.Extensions.BitmapConverter.ToMat(this.compositionSurface.Thumborigin)); this.compositionSurface = document.surface; if (IsCreatThumb) { //生成缩略图 this.compositionSurface.CreateThumbnail(); //生成原图的备份 //if (toedit) // this.compositionSurface.CreateThumborigin(); } this.baseRenderer.Source = document.surface; if (this.compositionSurface != null) { this.rendererList.SourceSize = this.compositionSurface.Size; this.rendererList.DestinationSize = this.Size; } this.document.Invalidated += Document_Invalidated; this.document.Metadata.Changed += DocumentMetaDataChangedHandler; } 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 => _activeTool; set { if (!tools.ContainsKey(value)) return; if (value == DrawToolType.DrawAutoRuler || value == DrawToolType.DrawPrestoredRuler || value == DrawToolType.DrawDateMark || value == DrawToolType.DrawTimeMark || value == DrawToolType.DrawGainNumber) { tools[value].InvokeMember("addWithNewObject", BindingFlags.Public | BindingFlags.Static | BindingFlags.InvokeMethod, null, null, new object[1] { this }); } else { tools[_activeTool].InvokeMember("beginWithNewObject", BindingFlags.Public | BindingFlags.Static | BindingFlags.InvokeMethod, null, null, new object[0] { }); } //tools[this.activeTool].beginWithNewObject(); if (value != DrawToolType.Pointer && value != DrawToolType.InclusionNoEffect && this.appWorkspace.GetScriptRunning()) this.appWorkspace.SetScriptStopping(true); else if (value == DrawToolType.Pointer) { this.appWorkspace.SetScriptStopping(false); //this.appWorkspace.ResumeScriptRunning(); } _activeTool = value; } } private void HookMouseEvents(Control c) { /** if (this.inkAvailable) { // This must be in a separate function, otherwise we will throw an exception when JITting // because MS.Ink.dll won't be available // This is to support systems that don't have ink installed try { Ink.HookInk(this, c); } catch (InvalidOperationException ioex) { Tracing.Ping("Exception while initializing ink hooks: " + ioex.ToString()); this.inkAvailable = false; } }**/ //暂时注释掉 /** c.MouseEnter += new EventHandler(this.MouseEnterHandler); c.MouseLeave += new EventHandler(this.MouseLeaveHandler); c.MouseUp += new MouseEventHandler(this.MouseUpHandler); c.MouseMove += new MouseEventHandler(this.MouseMoveHandler); c.MouseDown += new MouseEventHandler(this.MouseDownHandler); c.Click += new EventHandler(this.ClickHandler); foreach (Control c2 in c.Controls) { HookMouseEvents(c2); }**/ } private void UpdateRulerOffsets() { this.topRuler.Offset = ScaleFactor.UnscaleScalar(UI.ScaleWidth(-16.0f) - this.panel.Location.X); this.topRuler.Update(); this.leftRuler.Offset = ScaleFactor.UnscaleScalar(0.0f - this.panel.Location.Y); this.leftRuler.Update(); } 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); } } //暂时注释掉,因为在预览窗口、位置导航等显示标尺的时候,会闪烁,不知道会不会有啥问题 this.UpdateRulerOffsets(); this.UpdateImgLocation(); } 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); } } protected void UpdateComposition(bool raiseEvent) { lock (this) { /*using (RenderArgs ra = new RenderArgs(this.compositionSurface)) { bool result = this.document.Update(ra); if (raiseEvent && (result || this.withheldCompositionUpdatedCount > 0)) { OnCompositionUpdated(); if (!result && this.withheldCompositionUpdatedCount > 0) { --this.withheldCompositionUpdatedCount; } } else if (!raiseEvent && result) { // If they want to not raise the event, we must keep track so that // the next time UpdateComposition() is called we still raise this // event even if Update() returned false (which indicates there // was nothing to update) ++this.withheldCompositionUpdatedCount; } }*/ } } /// /// 重新设置中心点 /// /// 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); } } /// /// 获取当前文档的视场、标注、测量的xml数据 /// /// /// public List GetXmlFromViewOrLabelOrMeasure(DrawClass drawClass) { List topLVMModels = new List(); if (this.GraphicsList != null && this.GraphicsList.Count > 0) { for (int i = this.GraphicsList.Count - 1; i >= 0; i--) { ViewModel model = new ViewModel(); if (this.GraphicsList[i].objectType == drawClass) { model.Type = this.GraphicsList[i].drawToolType.ToString(); model.CombineMode = ((ViewBase)(this.GraphicsList[i])).combineMode.ToString(); model.Rectangle = this.GraphicsList[i].Rectangle; model.Points = this.GraphicsList[i].GetPoints(); model.StartPoint = this.GraphicsList[i].startPoint; model.EndPoint = this.GraphicsList[i].endPoint; topLVMModels.Add(model); } } } return topLVMModels; } /// /// 从打开视场窗口添加视场到DocumentView /// /// public void AddGraphicsFromForm(DrawObject drawObject) { this.GraphicsList.UnselectAll(); this.GraphicsList.Add(drawObject); this.Capture = true; this.Refresh(); this.SetDirty(); } #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 Ruler) { 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 Ruler) { 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.Clear(); //this.phaseModels.AddRanage(value); this.phaseModels = value; this.appWorkspace.GetPanelBottom().documentStrip.ClearPhase(); this.appWorkspace.GetPanelBottom().documentStrip.AddPhase(this.phaseModels); this.Refresh(); } 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); } /// /// 鼠标按下事件 /// /// /// protected virtual void MouseEvent_Down(object sender, MouseEventArgs e) { if (tools != null) { //tools[activeTool].OnMouseDown(this, e); tools[_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(); } } [DllImport("user32.dll", EntryPoint = "mouse_event", SetLastError = true)] private static extern int mouse_event(int dwFlags, int dx, int dy, int cButtons, int a); public void MouseEvent_Del(object sender, MouseEventArgs e) { try { tools[_activeTool].InvokeMember("beginWithNewObject", BindingFlags.Public | BindingFlags.Static | BindingFlags.InvokeMethod, null, null, new object[0] { }); tools[0].InvokeMember("OnDelKeyDown", BindingFlags.Public | BindingFlags.Static | BindingFlags.InvokeMethod, null, null, new object[2] { this, e }); } catch { } if (this.appWorkspace != null) { this.appWorkspace.RefreshLabelListDialog(); this.appWorkspace.RefreshMeasureListView(); } } /// /// 鼠标移动事件 /// /// /// protected virtual void MouseEvent_Move(object sender, MouseEventArgs e) { // // 是否绘制辅助线 // 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) if (tools != null) { tools[_activeTool].InvokeMember("OnMouseMove", BindingFlags.Public | BindingFlags.Static | BindingFlags.InvokeMethod, null, null, new object[2] { this, e }); } else this.Cursor = Cursors.Default; } /// /// 鼠标抬起事件 /// /// /// private void MouseEvent_Up(object sender, MouseEventArgs e) { if (tools != null) { if (e.Button == MouseButtons.Left) tools[_activeTool].InvokeMember("OnMouseUp", BindingFlags.Public | BindingFlags.Static | BindingFlags.InvokeMethod, null, null, new object[2] { this, e }); //tools[activeTool].OnMouseUp(this, e); } if (this.appWorkspace != null) { this.appWorkspace.RefreshLabelListDialog(); this.appWorkspace.RefreshMeasureListView(); this.appWorkspace.RefreshListView(); this.appWorkspace.RefreshOpticalDensity(); } } /// /// 鼠标单击事件 /// /// /// private void MouseEvent_Click(object sender, MouseEventArgs e) { if (tools != null) { tools[_activeTool].InvokeMember("OnMouseClick", BindingFlags.Public | BindingFlags.Static | BindingFlags.InvokeMethod, null, null, new object[2] { this, e }); //tools[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 { if (tools != null) { tools[_activeTool].InvokeMember("OnMouseLeftDoubleClick", BindingFlags.Public | BindingFlags.Static | BindingFlags.InvokeMethod, null, null, new object[2] { this, e }); } } } //tools[activeTool].OnMouseLeftDoubleClick(this, e); } /// /// 获取panel显示内容 生成图片返回 /// /// public Bitmap panelBitmap(bool nail = false) { if (compositionSurface == null) { return null; } Bitmap origin = compositionSurface.CreateAliasedBitmap(); Bitmap newBit = null; if (!nail) { newBit = origin; } else if (origin.Width > origin.Height) { newBit = Surface.MakeThumbnail(origin, 64, 64, "W"); } else if (origin.Height > origin.Width) { newBit = Surface.MakeThumbnail(origin, 64, 64, "H"); } else { newBit = Surface.MakeThumbnail(origin, 64, 64, "W"); } 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 unsafe void panelPaint(object sender, PaintEventArgs e) { 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) ? this.panel.AutoScrollPosition.X + offsetHalfW : (rc.Width - width) / 2; int y = (rc.Height < height) ? this.panel.AutoScrollPosition.Y + offsetHalfH : (rc.Height - height) / 2; //第四个版本,只绘制当前需要显示的大小的图片 //if (this.compositionSurface.Bitmap != null) if (this.compositionSurface.CreateAliasedBitmap() != null) { using (Surface doubleBuffer = GetDoubleBuffer(new Size((rc.Width < width) ? rc.Width : width, (rc.Height < height) ? rc.Height : height))) { try { using (RenderArgs renderArgs = new RenderArgs(doubleBuffer)) { DrawArea(renderArgs, new Point((rc.Width < width) ? -x : 0, (rc.Height < height) ? -y : 0)); if (m_center) { e.Graphics.DrawImage(doubleBuffer.CreateAliasedBitmap(), (rc.Width < width) ? 0 : (rc.Width - width) / 2, (rc.Height < height) ? 0 : (rc.Height - height) / 2, (rc.Width < width) ? rc.Width : width, (rc.Height < height) ? rc.Height : height); } else { e.Graphics.DrawImage(doubleBuffer.CreateAliasedBitmap(), m_pLeft, m_pTop, (rc.Width < width) ? rc.Width : width, (rc.Height < height) ? rc.Height : height); } } } catch { } } } // // 绘制选择的矩形 // 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) { int TopIndex = -1; foreach (PhaseModel model in phaseModels) { TopIndex++; if (model == null || model.mat == null || model.choise==false) continue; using (Surface doubleBufferA = GetDoubleBuffer(new Size((rc.Width < width) ? rc.Width : width, (rc.Height < height) ? rc.Height : height))) { try { using (RenderArgs renderArgs = new RenderArgs(doubleBufferA)) { DrawArea1(renderArgs, new Point((rc.Width < width) ? -x : 0, (rc.Height < height) ? -y : 0), TopIndex); if (m_center) { e.Graphics.DrawImage(doubleBufferA.CreateAliasedBitmap(), (rc.Width < width) ? 0 : (rc.Width - width) / 2, (rc.Height < height) ? 0 : (rc.Height - height) / 2, (rc.Width < width) ? rc.Width : width, (rc.Height < height) ? rc.Height : height); } else { e.Graphics.DrawImage(doubleBufferA.CreateAliasedBitmap(), m_pLeft, m_pTop, (rc.Width < width) ? rc.Width : width, (rc.Height < height) ? rc.Height : height); } } } catch { } } } } // // 以下是绘制相 // /*if (phaseModels.Count > 0) { foreach (PhaseModel model in phaseModels) { if (model != null && model.choise && model.mat != null && !model.mat.IsDisposed) { 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; //实际宽度 int actualHeight = AppWorkspaceTop.GetGridModel().grid.ActualHeight; //实际高度 if (unit == (int)MeasurementUnit.Micron) { AppWorkspaceTop.GetGridModel().grid.SideLength = (int)((double)actualLength / unitLength); AppWorkspaceTop.GetGridModel().grid.SideHeight = (int)((double)actualHeight / 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) { double unitLength = this.GetRuler(MeasurementUnit.Micron); //获取标尺 int unit = AppWorkspaceTop.GetGridModel().grid.Unit; //单位 int actualLength = AppWorkspaceTop.GetGridModel().rectangle.ActualLength; //实际边长 if (unit == (int)MeasurementUnit.Micron) { AppWorkspaceTop.GetGridModel().rectangle.sideLength = (int)((double)actualLength / unitLength); } DrawRulerHelper.drawGridRectangle(AppWorkspaceTop.GetGridModel(), e.Graphics, this.compositionSurface.Width, this.compositionSurface.Height, micronRatio); } // //以下是绘制圆形网格 // if (this.gridRoundEnabled && this.AppWorkspaceTop != null && micronRatio > 0) { double unitLength = this.GetRuler(MeasurementUnit.Micron); //获取标尺 int unit = AppWorkspaceTop.GetGridModel().grid.Unit; //单位 int actualDiameter = AppWorkspaceTop.GetGridModel().round.ActualDiameter; //实际直径 if (unit == (int)MeasurementUnit.Micron) { AppWorkspaceTop.GetGridModel().round.diameter = (int)((double)actualDiameter / unitLength); } 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); } } #endregion /// /// 获取panel可见位置的图片 /// /// public Bitmap GetClientRangePic() { 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; if (this.compositionSurface.CreateAliasedBitmap() != null) { using (Surface doubleBuffer = GetDoubleBuffer(new Size((rc.Width < width) ? rc.Width : width, (rc.Height < height) ? rc.Height : height))) { using (RenderArgs renderArgs = new RenderArgs(doubleBuffer)) { DrawArea(renderArgs, new Point((rc.Width < width) ? -x : 0, (rc.Height < height) ? -y : 0)); return doubleBuffer.CreateAliasedBitmap(); } } } return this.compositionSurface.CreateAliasedBitmap(); /*IntPtr handle = this.panel.Handle; IntPtr hdcSrc = SafeNativeMethods.GetWindowDC(handle); SafeNativeMethods.RECT windowRect = new SafeNativeMethods.RECT(); SafeNativeMethods.GetWindowRect(handle, ref windowRect); int width = windowRect.right - windowRect.left - ((this.panel.VerticalScroll.Visible) ? 18 : 0); int height = windowRect.bottom - windowRect.top - ((this.panel.HorizontalScroll.Visible) ? 18 : 0); IntPtr hdcDest = SafeNativeMethods.CreateCompatibleDC(hdcSrc); IntPtr hBitmap = SafeNativeMethods.CreateCompatibleBitmap(hdcSrc, width, height); IntPtr hOld = SafeNativeMethods.SelectObject(hdcDest, hBitmap); SafeNativeMethods.BitBlt(hdcDest, 0, 0, width, height, hdcSrc, 0, 0, SafeNativeMethods.SRCCOPY); SafeNativeMethods.SelectObject(hdcDest, hOld); SafeNativeMethods.DeleteDC(hdcDest); SafeNativeMethods.ReleaseDC(handle, hdcSrc); Bitmap img = Image.FromHbitmap(hBitmap); SafeNativeMethods.DeleteObject(hBitmap); return img;*/ } #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.VisibleDocumentRectangleF; //return this.AppWorkspaceTop.GetVisibleDocumentRectangleF(); } public SizeF GetDocumentSize() { if (this.Document != null) return this.Document.Size; else return new SizeF(0, 0); //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.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: path.AddClosedCurve(view.Points.ToArray()); break; case DrawToolType.ViewCircle: path.AddEllipse(view.Rectangle); 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 Container(); this.contextMenuStrip1 = new System.Windows.Forms.ContextMenuStrip(this.components); this.topRuler = new Ruler(); this.leftRuler = new Ruler(); this.panel = new PanelEx(); 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.panelBottom = new PanelBottom(); //this.panelBottom.SuspendLayout(); this.panel.SuspendLayout(); this.contextMenuStrip1.SuspendLayout(); this.SuspendLayout(); // // topRuler // this.topRuler.BackColor = Color.White; this.topRuler.Dock = DockStyle.Top; this.topRuler.Location = new Point(0, 0); this.topRuler.Name = "topRuler"; this.topRuler.Offset = -16; this.topRuler.Size = UI.ScaleSize(new Size(384, 16)); this.topRuler.TabIndex = 3; // // leftRuler // this.leftRuler.BackColor = Color.White; this.leftRuler.Dock = DockStyle.Left; this.leftRuler.Location = new Point(0, 16); this.leftRuler.Name = "leftRuler"; this.leftRuler.Orientation = Orientation.Vertical; this.leftRuler.Size = UI.ScaleSize(new Size(16, 304)); this.leftRuler.TabIndex = 4; // // panel // this.panel.ContextMenuStrip = this.contextMenuStrip1; this.panel.AutoScroll = true; this.panel.Dock = DockStyle.Fill; this.panel.Location = new Point(16, 16); this.panel.Name = "panel"; this.panel.ScrollPosition = new Point(0, 0); this.panel.Size = new Size(368, 304); this.panel.TabIndex = 5; this.panel.AllowDrop = false; this.panel.Scroll += new ScrollEventHandler(this.Panel_Scroll); this.panel.KeyDown += new KeyEventHandler(Panel_KeyDown); this.panel.KeyUp += new KeyEventHandler(Panel_KeyUp); this.panel.KeyPress += new KeyPressEventHandler(Panel_KeyPress); this.panel.GotFocus += new EventHandler(Panel_GotFocus); this.panel.LostFocus += new EventHandler(Panel_LostFocus); // // 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(69, 48); //this.contextMenuStrip1.Opening += new System.ComponentModel.CancelEventHandler(this.ContextMenuStrip1_Opening); this.contextMenuStrip1.Visible = false; // // // toolStripMenuItem1 // this.toolStripMenuItem1.Name = "toolStripMenuItem1"; this.toolStripMenuItem1.Text = PdnResources.GetString("Menu.Setting.MeasureSetting.Text"); this.toolStripMenuItem1.Size = new System.Drawing.Size(68, 22); this.toolStripMenuItem1.Click += new System.EventHandler(this.ToolStripMenuItem1_Click); this.toolStripMenuItem1.Visible = false; // // toolStripMenuItem2 // this.toolStripMenuItem2.Name = "toolStripMenuItem2"; this.toolStripMenuItem2.Text = PdnResources.GetString("Menu.Setting.LabelSetting.Text"); this.toolStripMenuItem2.Size = new System.Drawing.Size(68, 22); this.toolStripMenuItem2.Click += new System.EventHandler(this.ToolStripMenuItem2_Click); this.toolStripMenuItem2.Visible = false; // // toolStripMenuItem3 // this.toolStripMenuItem3.Name = "toolStripMenuItem3"; this.toolStripMenuItem3.Text = PdnResources.GetString("Menu.3celaing.Text"); this.toolStripMenuItem3.Size = new System.Drawing.Size(68, 22); this.toolStripMenuItem3.Click += new System.EventHandler(this.ToolStripMenuItem3_Click); this.toolStripMenuItem3.Visible = false; // // toolStripMenuItem4 // this.toolStripMenuItem4.Name = "toolStripMenuItem4"; this.toolStripMenuItem4.Text = PdnResources.GetString("Menu.biaozhushuxing.Text"); this.toolStripMenuItem4.Size = new System.Drawing.Size(68, 22); this.toolStripMenuItem4.Click += new System.EventHandler(this.ToolStripMenuItem4_Click); this.toolStripMenuItem4.Visible = false; // 底部的panelBottom // /*this.panelBottom.Size = new Size(384, 30); this.panelBottom.Anchor = AnchorStyles.Left | AnchorStyles.Right | AnchorStyles.Bottom; this.panelBottom.Dock = DockStyle.Bottom; this.panelBottom.trackBar.ValueChanged += new EventHandler(this.PanelBottom_trackBar_ValueChanged); this.panelBottom.BackColor = Color.FromArgb(240, 240, 240);*/ // // DocumentView // this.Controls.Add(this.panel); this.Controls.Add(this.leftRuler); this.Controls.Add(this.topRuler); //this.Controls.Add(this.panelBottom); this.Name = "DocumentView"; this.Size = new System.Drawing.Size(384, 320); this.panel.ResumeLayout(false); //this.panelBottom.ResumeLayout(false); this.contextMenuStrip1.ResumeLayout(false); this.ResumeLayout(false); } public virtual 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) { if (IsScratchesOrStains()) { contextMenuStrip1.Visible = false; this.toolStripMenuItem1.Visible = false; this.toolStripMenuItem2.Visible = false; this.toolStripMenuItem3.Visible = false; this.toolStripMenuItem4.Visible = false; } else { 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; } } //是否是污迹或者划痕处理 bool IsScratchesOrStains() { bool IsScratchesOrStains = false; for (int i = 0; i < this.GraphicsList.Count; i++) { if (this.GraphicsList[i].Selected) { //判断如果是划痕处理 if (this.GraphicsList[i].drawToolType == DrawToolType.DrawScratchTreatmentLine || this.GraphicsList[i].drawToolType == DrawToolType.DrawSmudgeRectangle || this.GraphicsList[i].drawToolType == DrawToolType.DrawSmudgePolygon || this.GraphicsList[i].drawToolType == DrawToolType.DrawSmudgeCircle || this.GraphicsList[i].drawToolType == DrawToolType.DrawSmudgeEllipse) { IsScratchesOrStains = true; } } } return IsScratchesOrStains; } #endregion #region 设定图片位置 // add by maxb 20200716 /// /// 图片位置坐标 /// private bool m_center = true; private int m_pTop = 0; private int m_pLeft = 0; private int m_initTop = 0; private int m_initLeft = 0; public void SetDocumentPoint(int x, int y) { m_center = false; m_initLeft = x; m_initTop = y; UpdateImgLocation(); this.Refresh(); } public void SetCenter(bool center) { m_center = center; } private void UpdateImgLocation() { if (!m_center) { //Console.WriteLine("m_pLeft: " + m_initLeft + " Ratio:" + this.scaleFactor.Ratio); m_pLeft = 16 + (int)(m_initLeft * this.scaleFactor.Ratio); m_pTop = 16 + (int)(m_initTop * this.scaleFactor.Ratio); //Console.WriteLine("Location: " + m_pLeft + " " + m_pTop); } } #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[_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 = m_pLeft; int y = m_pTop; tools[_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(); /// /// AxioVision标尺单位对应 /// public Dictionary rule = new Dictionary() { { 76, MeasurementUnit.Micron},{75, MeasurementUnit.Millimeter},{ 74, MeasurementUnit.Centimeter}, { 77, MeasurementUnit .Nano} ,{ 81, MeasurementUnit.Inch},{ 84, MeasurementUnit.Mil} }; ///// ///// 系统内选定的单位 ///// //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; } /// /// 获取AxioVision标尺(提取方式不确定,后续实时变更) /// RuleAttr[0]单位标识,RuleAttr[1]标尺长度 /// /// 标尺路径 /// public mic_rulers RuleAttribute(string name,double rulerData, MeasurementUnit measurement,decimal gain_multiple) { this.xmlSaveModel = new mic_rulers(); this.xmlSaveModel.ruler_name = name; this.xmlSaveModel.gain_multiple = gain_multiple; this.xmlSaveModel.pixel_length = 100; this.xmlSaveModel.physical_length = Convert.ToDecimal(100 * rulerData); this.xmlSaveModel.ruler_units = (int)measurement; 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() { List mic_rulersAll = Mic_rulersAll(); if (this.xmlSaveModel == null && mic_rulersAll.Count > 0) this.xmlSaveModel = mic_rulersAll[0]; 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.Mil, 1000 * 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.Mil://米尔 this.rules.Add(MeasurementUnit.Inch, 0.001 * unitLength); //英寸 this.rules.Add(MeasurementUnit.Mil, unitLength); //米尔 this.rules.Add(MeasurementUnit.Centimeter, 0.00254 * unitLength); //厘米 this.rules.Add(MeasurementUnit.Millimeter, 0.0254 * unitLength); //毫米 this.rules.Add(MeasurementUnit.Micron, 25.4 * unitLength); //微米 this.rules.Add(MeasurementUnit.Nano, 25400 * unitLength); //纳米 break; case (int)MeasurementUnit.Centimeter://厘米 this.rules.Add(MeasurementUnit.Inch, 0.3937008 * unitLength); //英寸 this.rules.Add(MeasurementUnit.Mil, 393.7008 * 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.Mil, 39.3701 * 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.Mil, 0.03937007874 * 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.Mil, 3.9370e-5 * 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.Mil, 0.0394); //米尔 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); } /// /// 获取单位标尺 /// /// 度量单位的枚举 /// 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 double GetMultiple() { double multiple = 1; if (this.xmlSaveModel != null) { multiple = (double)this.xmlSaveModel.gain_multiple; } return multiple; } /// /// 获取单位标尺乘以放大倍数 /// /// 度量单位的枚举 /// public double GetRulerMultiple(MeasurementUnit measurementUnit) { double unitLength = 0; double multiple = 0; //判断当前图片是否有对应的标尺 if (this.rules.Count > 0) { this.rules.TryGetValue(measurementUnit, out unitLength); } else { this.appWorkspace.getMeasureInfo().TryGetValue(MeasurementUnit.Micron, out unitLength); } if (this.xmlSaveModel != null) { multiple = (double)this.xmlSaveModel.gain_multiple; } return unitLength * multiple; } public void SetContinuousDrawingLabel(bool v) { ContinuousDrawingLabel = v; appWorkspace.SetContinuousDrawingLable(v); } public void SetContinuousDrawingMeasure(bool v) { ContinuousDrawingMeasure = v; appWorkspace.SetContinuousDrawingMeasure(v); } #endregion public Dictionary GetTools() { return tools; } public MeasurementUnit GetMeasurementUnit() { return this.Units; } public Inclusion GetInclusion() { return this.inclusion; } } }