using System; using System.Collections.Generic; using System.Drawing; using System.Drawing.Drawing2D; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Forms; using PaintDotNet.Annotation.Enum; using PaintDotNet.Base.SettingModel; using static PaintDotNet.Base.SettingModel.LabelStyleModel; namespace PaintDotNet.Annotation.ImageCollect { /// /// 图像拼接 - 矩形 /// public class DrawStitchingRectangle : DrawStithchingBase { /// /// 标注样式信息model /// public PolygonRectangle labelRectStyleModel; public DrawStitchingRectangle(ISurfaceBox surfaceBox, int x, int y, int width, int height) : base() { this.deletedPointId = new List(); this._points = new List>(); this.objectType = DrawClass.Stitch; this.drawToolType = DrawToolType.DrawStitchingRectangle; this.labelRectStyleModel = surfaceBox.GetLabelStyleModel().polygonRectangle; this.ISurfaceBox = surfaceBox; this.rectangle.X = x; this.rectangle.Y = y; this.rectangle.Width = width; this.rectangle.Height = height; Initialize(); } public DrawStitchingRectangle(ISurfaceBox surfaceBox, List points, ParentStyleModel parentStyleModel) : base() { this.deletedPointId = new List(); this._points = new List>(); this.objectType = DrawClass.Stitch; this.drawToolType = DrawToolType.DrawStitchingRectangle; this.ISurfaceBox = surfaceBox; labelRectStyleModel = (PolygonRectangle)parentStyleModel; rectangle.X = points[0].X; rectangle.Y = points[0].Y; rectangle.Width = points[1].X - points[0].X; rectangle.Height = points[1].Y - points[0].Y; } /// /// Clone this instance /// public override DrawObject Clone() { DrawStitchingRectangle drawRectangle = new DrawStitchingRectangle(ISurfaceBox, 0, 0, 1, 0); drawRectangle.objectType = DrawClass.Stitch; drawRectangle.drawToolType = DrawToolType.DrawStitchingRectangle; drawRectangle.ISurfaceBox = this.ISurfaceBox; drawRectangle.rectangle = this.rectangle; FillDrawObjectFields(drawRectangle); return drawRectangle; } public override DrawObject Clone(ISurfaceBox surfaceBox) { DrawStitchingRectangle drawRectangle = new DrawStitchingRectangle(surfaceBox, 0, 0, 1, 0); drawRectangle.objectType = DrawClass.Stitch; drawRectangle.drawToolType = DrawToolType.DrawStitchingRectangle; drawRectangle.ISurfaceBox = surfaceBox; drawRectangle.rectangle = this.rectangle; drawRectangle.labelRectStyleModel = this.labelRectStyleModel; FillDrawObjectFields(drawRectangle); return drawRectangle; } /// /// Draw rectangle /// /// public override void Draw(Graphics g) { Color color = Color.Gray; Pen pen = new Pen(color, PenWidth); int penWidth = 1; //this.labelRectStyleModel.lineWidth; pen.DashStyle = DashStyle.Solid; // (DashStyle)this.labelRectStyleModel.lineStyle; pen.Width = penWidth; var rettmp = new RectangleF(rectangle.X + OffsetX, rectangle.Y + OffsetY, rectangle.Width, rectangle.Height); g.DrawRectangle(pen, DrawStitchingRectangle.GetNormalizedRectangle(rettmp)); pen.Color = Color.FromArgb(this.labelRectStyleModel.lineColor); //fillBrush.Dispose(); float halfW = rectangle.Width / 2; float halfH = rectangle.Height / 2; int xNum = CalGridNum(rectangle.Width, ViewWidth); int yNum = CalGridNum(rectangle.Height, ViewHeight); if (xNum != tiles[0] || yNum != tiles[1]) { tiles[0] = xNum; tiles[1] = yNum; this.deletedPointId.Clear(); this.zscan.Clear(); for (int j = 0; j < tiles[1]; j++) { for (int i = 0; i < tiles[0]; i++) { zscan.Add(new ZScanParameter()); } } } PointF centerPoint = new PointF(); centerPoint.X = rectangle.X + halfW; centerPoint.Y = rectangle.Y + halfH; PointF startPoint = new PointF(); if (tiles[0] % 2 == 0) { startPoint.X = (float)centerPoint.X - ViewWidth * (tiles[0] / 2 - Interval / 2 - (tiles[0] / 2 - 1) * Interval); } else { int n = (tiles[0] - 1) / 2; startPoint.X = (float)centerPoint.X - ViewWidth / 2 - n * ViewWidth * (1 - Interval); } if (tiles[1] % 2 == 0) { startPoint.Y = (float)centerPoint.Y - ViewHeight * (tiles[1] / 2 - Interval / 2 - (tiles[1] / 2 - 1) * Interval); } else { int n = (tiles[1] - 1) / 2; startPoint.Y = (float)centerPoint.Y - ViewHeight / 2 - n * ViewHeight * (1 - Interval); } rectangleMax = new RectangleF(startPoint, new SizeF(ViewWidth * (tiles[0] - (tiles[0] - 1) * Interval), ViewHeight * (tiles[1] - (tiles[1] - 1) * Interval))); _points.Clear(); List tmpList; int index = 0; for (int j = 0; j < tiles[1]; j++) { tmpList = new List(); for (int i = 0; i < tiles[0]; i++) { float x = startPoint.X + i * (ViewWidth * (1 - Interval)); float y = startPoint.Y + j * (ViewHeight * (1 - Interval)); tmpList.Add(new PointF(x, y)); } if (j % 2 == 1) { for (int m = tmpList.Count - 1; m >= 0; m--) { Dictionary myDictionary = new Dictionary(); myDictionary.Add(0, this.ISurfaceBox.ScalePointToRulerPoint(new PointF(tmpList[m].X, tmpList[m].Y))); if (!deletedPointId.Contains(index)) { g.DrawRectangle(pen, tmpList[m].X + OffsetX, tmpList[m].Y + OffsetY, ViewWidth, ViewHeight); myDictionary.Add(1, 0); } else { myDictionary.Add(1, 1); } _points.Add(myDictionary); index++; } } else { for (int m = 0; m < tmpList.Count; m++) { Dictionary myDictionary = new Dictionary(); myDictionary.Add(0, this.ISurfaceBox.ScalePointToRulerPoint(new PointF(tmpList[m].X, tmpList[m].Y))); if (!deletedPointId.Contains(index)) { g.DrawRectangle(pen, tmpList[m].X + OffsetX, tmpList[m].Y + OffsetY, ViewWidth, ViewHeight); myDictionary.Add(1, 0); } else { myDictionary.Add(1, 1); } _points.Add(myDictionary); index++; } } } pen.Dispose(); //OnPropertyChanged(); } private int CalGridNum(float width, int side) { for (int i = 0; i <= 10000; i++) { if ((i - (i + 1) * Interval) * side > width) { return i; } } return 0; } protected void SetRectangle(float x, float y, float width, float height) { this.rectangle.X = x; this.rectangle.Y = y; this.rectangle.Width = width; this.rectangle.Height = height; } /// /// Get number of handles /// public override int HandleCount { get { return 8; } } /// /// Get handle pointscroll by 1-based number /// /// /// public override PointF GetHandle(int handleNumber) { float x, y, xCenter, yCenter; xCenter = this.rectangle.X + this.rectangle.Width / 2; yCenter = this.rectangle.Y + this.rectangle.Height / 2; x = this.rectangle.X; y = this.rectangle.Y; switch (handleNumber) { case 1: x = this.rectangle.X; y = this.rectangle.Y; break; case 2: x = xCenter; y = this.rectangle.Y; break; case 3: x = this.rectangle.Right; y = this.rectangle.Y; break; case 4: x = this.rectangle.Right; y = yCenter; break; case 5: x = this.rectangle.Right; y = this.rectangle.Bottom; break; case 6: x = xCenter; y = this.rectangle.Bottom; break; case 7: x = this.rectangle.X; y = this.rectangle.Bottom; break; case 8: x = this.rectangle.X; y = yCenter; break; } return OffsetPointF(x, y); } public override Rectangle GetHandleRectangle(int handleNumber) { if (lockType == LockType.SIZE) { return new Rectangle(); } else if (lockType == LockType.AREA) { if (handleNumber % 2 == 1) { return new Rectangle(); } } PointF point = GetHandle(handleNumber); return new Rectangle((int)(point.X - 100), (int)(point.Y - 100), 201, 201); } /// /// Hit test. /// Return value: -1 - no hit /// 0 - hit anywhere /// > 1 - handle number /// /// /// public override int HitTest(Point point) { if (Selected) { for (int i = 1; i <= HandleCount; i++) { if (GetHandleRectangle(i).Contains(point)) return i; } } if (PointInObject(point)) return 0; return -1; } protected override bool PointInObject(Point point) { return rectangle.Contains(point); } /// /// Get cursor for the handle /// /// /// public override Cursor GetHandleCursor(int handleNumber) { switch (handleNumber) { case 1: return Cursors.SizeNWSE; case 2: return Cursors.SizeNS; case 3: return Cursors.SizeNESW; case 4: return Cursors.SizeWE; case 5: return Cursors.SizeNWSE; case 6: return Cursors.SizeNS; case 7: return Cursors.SizeNESW; case 8: return Cursors.SizeWE; default: return Cursors.Default; } } /// /// Move handle to new pointscroll (resizing) /// /// /// public override void MoveHandleTo(Point point, int handleNumber) { float left = Rectangle.Left; float top = Rectangle.Top; float right = Rectangle.Right; float bottom = Rectangle.Bottom; switch (handleNumber) { case 1: left = point.X; top = point.Y; break; case 2: top = point.Y; break; case 3: right = point.X; top = point.Y; break; case 4: right = point.X; break; case 5: right = point.X; bottom = point.Y; break; case 6: bottom = point.Y; break; case 7: left = point.X; bottom = point.Y; break; case 8: left = point.X; break; } float length = 0f; float xchange = 0f; if (lockType == LockType.AREA) { switch (handleNumber) { case 2: length = top - Rectangle.Top; xchange = (Rectangle.Width - (Rectangle.Width * Rectangle.Height) / (Rectangle.Height + length)) / 2; left = left + xchange; right = right - xchange; break; case 4: length = right - Rectangle.Right; xchange = (Rectangle.Height - (Rectangle.Width * Rectangle.Height) / (Rectangle.Width + length)) / 2; top = top + xchange; bottom = bottom - xchange; break; case 6: length = bottom - Rectangle.Bottom; xchange = (Rectangle.Width - (Rectangle.Width * Rectangle.Height) / (Rectangle.Height + length)) / 2; left = left + xchange; right = right - xchange; break; case 8: length = left - Rectangle.Left; xchange = (Rectangle.Height - (Rectangle.Width * Rectangle.Height) / (Rectangle.Width + length)) / 2; top = top + xchange; bottom = bottom - xchange; break; } } SetRectangle(left, top, right - left, bottom - top); } public override bool IntersectsWith(Rectangle rectangle) { return Rectangle.IntersectsWith(rectangle); } /// /// Move object /// /// /// public override void Move(int deltaX, int deltaY) { int x = ISurfaceBox.UnscaleScalar(deltaX); int y = ISurfaceBox.UnscaleScalar(deltaY); rectangle.X += x; rectangle.Y += y; } public override RectangleF GetBoundingBox() { return rectangle; } public override List GetPoints() { List points = new List(); points.Add(new PointF(rectangle.X, rectangle.Y)); points.Add(new PointF(rectangle.Right, rectangle.Bottom)); return points; } public override ParentStyleModel GetStyle() { return labelRectStyleModel; } } }