代码拉取完成,页面将自动刷新
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Imaging;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace OptikinetiqControls
{
/// <summary>
/// 显示模式
/// </summary>
enum DisplayMode
{
/// <summary>
/// 像素级
/// </summary>
Pixel,
/// <summary>
/// 高质量
/// </summary>
HighQuality
}
/// <summary>
/// 操作模式
/// </summary>
enum DrawMode
{
/// <summary>
/// 点
/// </summary>
Point,
/// <summary>
/// 线
/// </summary>
Line,
/// <summary>
/// 矩形
/// </summary>
Rectangle,
/// <summary>
/// 旋转矩形
/// </summary>
RotateRect,
/// <summary>
/// 椭圆
/// </summary>
Ellipse,
/// <summary>
/// 圆
/// </summary>
Circle,
/// <summary>
/// 多边形
/// </summary>
Polygon,
/// <summary>
/// 无操作
/// </summary>
None
}
enum DrawState
{
/// <summary>
/// 开始
/// </summary>
Start,
/// <summary>
/// 绘制中
/// </summary>
Drawing,
/// <summary>
/// 完成
/// </summary>
Finish,
/// <summary>
/// 移动中
/// </summary>
Moving,
/// <summary>
/// 绘制线起点拖动
/// </summary>
StartDraging,
/// <summary>
/// 绘制线终点拖动
/// </summary>
EndDraging,
/// <summary>
/// 圆形缩放拖动
/// </summary>
ScaleDraging,
/// <summary>
/// 矩形上边拖动
/// </summary>
TopDraging,
/// <summary>
/// 矩形下边拖动
/// </summary>
BottomDraging,
/// <summary>
/// 矩形左边拖动
/// </summary>
LeftDraging,
/// <summary>
/// 矩形右边拖动
/// </summary>
RightDraging,
/// <summary>
/// 矩形右下角拖动
/// </summary>
BrDraging,
/// <summary>
/// 旋转
/// </summary>
Rotate,
Done,
}
public partial class HaumDisplayWindow : UserControl
{
private Bitmap cloneBmp;
/// <summary>
/// 显示图像
/// </summary>
public Bitmap imageBmp;
/// <summary>
/// 图片文件路径
/// </summary>
public string imageFilePath;
/// <summary>
/// 缩放比例
/// </summary>
private float scaleF = 1.0f;
/// <summary>
/// 开始移动时鼠标位置
/// </summary>
private Point startMovePosition = Point.Empty;
/// <summary>
/// 当前图像基于原图偏移量
/// </summary>
private PointF offset = Point.Empty;
/// <summary>
/// 图像显示模式 : 高质量(平滑处理锯齿不失真), 像素级(能够清晰显示每一个像素,锯齿边缘明显,适合查看像素坐标与rgb值)
/// </summary>
private DisplayMode viewMode = DisplayMode.Pixel;
/// <summary>
/// 操作模式:记录操作模式或当前绘制图型类型
/// </summary>
private DrawMode operatorMode = DrawMode.None;
/// <summary>
/// 绘制状态标志位
/// </summary>
private DrawState drawState = DrawState.Done;
/// <summary>
/// 画笔粗细
/// </summary>
private int penSize = 1;
/// <summary>
/// 画笔颜色
/// </summary>
private Color penColor = Color.Green;
/// <summary>
/// 绘制点对象
/// </summary>
private DrawPoint drawPoint;
/// <summary>
/// 绘制线对象
/// </summary>
private DrawLine drawLine;
/// <summary>
/// 绘制矩形对象
/// </summary>
private DrawRectangle drawRectangle;
/// <summary>
/// 绘制椭圆
/// </summary>
private DrawEllipse drawEllipse;
/// <summary>
/// 绘制圆对象
/// </summary>
private DrawCircle drawCircle;
/// <summary>
/// 绘制多边形对象
/// </summary>
private DrawPolygon drawPolygon;
/// <summary>
/// 绘制可旋转矩形
/// </summary>
private DrawRotateRect drawRotateRect;
/// <summary>
/// 旋转光标
/// </summary>
private Cursor rotateCursor;
/// <summary>
/// 计时器
/// </summary>
private Stopwatch sw = new Stopwatch();
/// <summary>
/// 灰度直方器
/// </summary>
public IGrayscaleHistogram grayscaleHistogram;
/// <summary>
/// 初始化控件
/// </summary>
public HaumDisplayWindow()
{
InitializeComponent();
//绑定显示控件鼠标滑动事件 进行缩放
mainView.MouseWheel += mainView_MouseWheel;
// 启用控件双缓冲 防止控件重绘闪烁
this.DoubleBuffered = true;
this.SetStyle(ControlStyles.OptimizedDoubleBuffer | ControlStyles.ResizeRedraw | ControlStyles.AllPaintingInWmPaint, true);
//初始化旋转弧形鼠标样式
// 加载自定义光标文件,这里假设你有一个名为 custom_cursor.cur 的光标文件在项目目录下
using (MemoryStream ms = new MemoryStream(Properties.Resources.弧线))
{
rotateCursor = new Cursor(ms);
}
}
/// <summary>
/// 显示图片
/// </summary>
/// <param name="image">图片</param>
public void ShowImage(Bitmap image)
{
imageBmp = image;
cloneBmp = image;
this.Fit();
int width = image.Width;
int height = image.Height;
this.toolStripLabel1.Text = $"{width},{height}";
}
/// <summary>
/// 图像自适应
/// </summary>
public void Fit()
{
if (imageBmp == null) { return; }
//计算控件与图像的宽高比例
float scaleX = (float)(mainView.Width - 2) / imageBmp.Width;
float scaleY = (float)(mainView.Height - 2) / imageBmp.Height;
//获取较小的一边比例作为缩放比例
scaleF = Math.Min(scaleX, scaleY);
//计算缩放后的图像宽高值
int newWidth = (int)(imageBmp.Width * scaleF);
int newHeight = (int)(imageBmp.Height * scaleF);
//计算图像居中显示的位置
offset.X = (mainView.Width - newWidth) / 2;
offset.Y = (mainView.Height - newHeight) / 2;
//触发自身的Point方法进行控件重绘
mainView.Invalidate();
}
/// <summary>
/// 导入图片
/// </summary>
private void ImportImage()
{
//打开文件对话框进行选择图片并触发显示控件重绘
using (OpenFileDialog ofd = new OpenFileDialog())
{
ofd.Filter = "图像文件(*.bmp;*.png;*.jpg;*.jpeg;*.tiff)|*.bmp;*.png;*.jpg;*.jpeg;*.tiff|所有文件(*.*)|*.*";
ofd.Title = "选择导入并显示图片";
if (ofd.ShowDialog() == DialogResult.OK)
{
this.ShowImage(new Bitmap(ofd.FileName));
imageFilePath = ofd.FileName;
this.Fit();
}
}
}
/// <summary>
/// 移除图片
/// </summary>
private void RemoveImage()
{
if (imageBmp == null)
{
return;
}
imageBmp = null;
//cloneBmp = null;
mainView.Invalidate();
}
/// <summary>
/// 保存图片
/// </summary>
private bool SaveImage()
{
if (imageBmp == null)
{
return false;
}
//打开保存文件对话框保存图片
using (SaveFileDialog sfd = new SaveFileDialog())
{
sfd.Title = "保存图片到:";
sfd.DefaultExt = "bmp";
sfd.CheckPathExists = true;
sfd.Filter = "BMP|*.bmp|PNG|*.png|JPG|*.jpg|JPEG|*.jpeg|TIFF|*.tiff";
if (sfd.ShowDialog() == DialogResult.OK)
{
try
{
string extension = Path.GetExtension(sfd.FileName);
switch (extension.ToLower())
{
case ".bmp":
imageBmp.Save(sfd.FileName, ImageFormat.Bmp);
break;
case ".png":
imageBmp.Save(sfd.FileName, ImageFormat.Png);
break;
case ".jpg":
case ".jpeg":
imageBmp.Save(sfd.FileName, ImageFormat.Jpeg);
break;
case ".tiff":
imageBmp.Save(sfd.FileName, ImageFormat.Tiff);
break;
default:
break;
}
}
catch (Exception ex) {
return false;
}
}
}
return true;
}
private void ImageSaveByExtension(Image image, string Extension)
{
}
/// <summary>
/// 保存图片
/// </summary>
/// <param name="dir">文件夹路径</param>
/// <param name="name">文件名(带后缀)</param>
/// <param name="quality">压缩质量:当文件后缀名为jpg或jpeg时自动启用 取值范围(最差)0-100(最优)</param>
private void Save(string dir, string name, byte quality = 100)
{
string extension = Path.GetExtension(name);
//如果图像不存在或文件后缀不合理直接返回
if (imageBmp == null || extension == null || extension == string.Empty)
{
return;
}
//判断文件夹是否存在,如果不存在先创建文件夹
Directory.CreateDirectory(dir);
//组合保存全路径
string fullPath = Path.Combine(dir, name);
//将文件后缀名转小写
extension = extension.Trim().ToLower();
//判断文件后缀是否需要保存压缩
if (extension.Equals(".jpg") || extension.Equals(".jpeg"))
{
// 获取 JPEG 编码器
ImageCodecInfo jpegCodecInfo = GetEncoderInfo("image/jpeg");
// 创建 EncoderParameters 对象,设置压缩质量
EncoderParameters encoderParameters = new EncoderParameters(1);
encoderParameters.Param[0] = new EncoderParameter(System.Drawing.Imaging.Encoder.Quality, quality);
imageBmp.Save(fullPath, jpegCodecInfo, encoderParameters);
}
//不进行压缩
else
{
imageBmp.Save(fullPath);
}
}
/// <summary>
/// 检索图像编码器与解码器
/// </summary>
/// <param name="mimeType">"image/jpeg"</param>
/// <returns>ImageCodecInfo / None</returns>
private ImageCodecInfo GetEncoderInfo(string mimeType)
{
ImageCodecInfo[] codecs = ImageCodecInfo.GetImageEncoders();
for (int i = 0; i < codecs.Length; i++)
{
if (codecs[i].MimeType == mimeType)
{
return codecs[i];
}
}
return null;
}
/// <summary>
/// 判断鼠标是否在某一个控件上方
/// </summary>
/// <param name="e"></param>
/// <param name="control"></param>
/// <returns></returns>
private bool IsMouseOnCtrl(MouseEventArgs e, Control control)
{
int lx = 0;
int ly = 0;
int width = control.Width;
int height = control.Height;
if (e.X >= lx && e.X < width && e.Y >= ly && e.Y < height)
{
return true;
}
else
{
return false;
}
}
private void mainView_MouseMove(object sender, MouseEventArgs e)
{
if (imageBmp == null) { return; }
//实时计算拖动图片后的鼠标位置并重绘
if (mainView.Cursor == Cursors.Hand && e.Button == MouseButtons.Left && operatorMode == DrawMode.None)
{
Console.WriteLine("拖动图片中...");
int dx = e.X - startMovePosition.X;
int dy = e.Y - startMovePosition.Y;
if (Math.Abs(dx) > 1 || Math.Abs(dy) > 1)
{
offset.X += dx;
offset.Y += dy;
startMovePosition = e.Location;
}
}
//按住Ctrl键实时计算当前鼠标位置的像素值并显示
if (Control.ModifierKeys == Keys.Control && IsMouseOnCtrl(e, mainView))
{
Console.WriteLine($"正在按住Ctrl... X:{e.X} Y:{e.Y}");
//默认提示信息
string info = $"X:-- Y:-- \n\rR:-- G:-- B--";
// 计算鼠标在原始图片上的位置
PointF imagePoint = ScreenTransImagePointF(e.Location);
// 检查相对位置是否在图片范围内
if (imagePoint.X >= 0 && imagePoint.X < imageBmp.Width &&
imagePoint.Y >= 0 && imagePoint.Y < imageBmp.Height)
{
//获取图像上位置的RGB值
Color pixelColor = imageBmp.GetPixel((int)imagePoint.X, (int)imagePoint.Y);
//组合提示信息
info = $"X:{(int)imagePoint.X} Y:{(int)imagePoint.Y} \n\rR:{pixelColor.R} G:{pixelColor.G} B:{pixelColor.B}";
}
//显示提示
toolTip.Show(info, mainView, e.Location.X + 10, e.Location.Y + 15);
}
else
{
toolTip.Hide(mainView);
}
switch (operatorMode)
{
case DrawMode.Point:
DrawPoint(e);
break;
case DrawMode.Line:
DrawLine(e);
break;
case DrawMode.Rectangle:
DrawRectangle(e);
break;
case DrawMode.Circle:
DrawCircle(e);
break;
case DrawMode.RotateRect:
DrawRotateRect(e);
break;
case DrawMode.Polygon:
DrawPolygon(e);
break;
}
mainView.Invalidate();
}
private bool IsMouseOnImage(Point mouseLocation)
{
PointF imageLoca = ScreenTransImagePointF(mouseLocation);
if (imageLoca.X >= 0 && imageLoca.X < imageBmp.Width && imageLoca.Y >= 0 && imageLoca.Y < imageBmp.Height)
{
return true;
}
else
{
return false;
}
}
/// <summary>
/// 鼠标滚轮滚动事件
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void mainView_MouseWheel(object sender, MouseEventArgs e)
{
if (imageBmp != null)
{
float zoomFactor = e.Delta > 0 ? 1.1f : 0.9f;
float oldScale = scaleF;
scaleF *= zoomFactor;
// 限制缩放范围
if (scaleF < 0.01f) scaleF = 0.01f;
if (scaleF > 100.0f) scaleF = 100.0f;
// 根据鼠标位置调整偏移量
float dx = (float)e.X - offset.X;
float dy = (float)e.Y - offset.Y;
offset.X -= dx * (scaleF / oldScale - 1);
offset.Y -= dy * (scaleF / oldScale - 1);
mainView.Invalidate();
}
}
/// <summary>
/// 将控件坐标点转为图像坐标点
/// </summary>
/// <param name="screenPoint">一个控件坐标点</param>
/// <returns>图像坐标</returns>
private PointF ScreenTransImagePointF(Point screenPoint)
{
// 计算鼠标在原始图片上的相对位置
float relativeX = (screenPoint.X - offset.X) / scaleF;
float relativeY = (screenPoint.Y - offset.Y) / scaleF;
return new PointF(relativeX, relativeY);
}
/// <summary>
/// 将图像坐标点转为控件坐标点
/// </summary>
/// <param name="imagePoint">一个图像坐标点</param>
/// <returns>控件坐标</returns>
private Point ImageTransScreenPoint(Point imagePoint)
{
float relativeX = imagePoint.X * scaleF + offset.X;
float relativeY = imagePoint.Y * scaleF + offset.Y;
return new Point((int)relativeX, (int)relativeY);
}
/// <summary>
/// 将图像坐标点转为控件坐标点
/// </summary>
/// <param name="imagePoint">一个图像坐标点</param>
/// <returns>控件坐标</returns>
private PointF ImageTransScreenPointF(PointF imagePoint)
{
float relativeX = imagePoint.X * scaleF + offset.X;
float relativeY = imagePoint.Y * scaleF + offset.Y;
return new PointF(relativeX, relativeY);
}
/// <summary>
/// 将图像坐标点集转为控件坐标点集
/// </summary>
/// <param name="imagePoint">一个图像坐标点</param>
/// <returns>控件坐标</returns>
private List<PointF> ImageTransScreenPointF(List<PointF> imagePoints)
{
List<PointF> ps = new List<PointF>();
for (int i = 0; i < imagePoints.Count; i++)
{
PointF p = ImageTransScreenPointF(imagePoints[i]);
ps.Add(p);
}
return ps;
}
private void PaintPoint(PaintEventArgs e)
{
using (Pen pen = new Pen(drawPoint.penColor, drawPoint.penSize))
{
PointF controlPoint = ImageTransScreenPointF(drawPoint.point);
float length = 5 * scaleF;
// 绘制垂直的线(中心点上下各 5 像素)
e.Graphics.DrawLine(pen, controlPoint.X, controlPoint.Y - length, controlPoint.X, controlPoint.Y + length);
// 绘制水平的线(中心点左右各 5 像素)
e.Graphics.DrawLine(pen, controlPoint.X - length, controlPoint.Y, controlPoint.X + length, controlPoint.Y);
}
}
private void PaintLine(PaintEventArgs e)
{
using (Pen pen = new Pen(drawLine.penColor, drawLine.penSize))
{
using (Pen selectPen = new Pen(drawLine.isSelect ? drawLine.selectColor : drawLine.penColor, drawLine.penSize + 1))
{
//绘制起点中点终点
PointF start = ImageTransScreenPointF(drawLine.startPoint);
PointF center = ImageTransScreenPointF(drawLine.GetCenter());
PointF end = ImageTransScreenPointF(drawLine.endPoint);
e.Graphics.DrawEllipse(selectPen, start.X - 1, start.Y - 1, 2, 2);
e.Graphics.DrawEllipse(selectPen, center.X - 1, center.Y - 1, 2, 2);
e.Graphics.DrawEllipse(selectPen, end.X - 1, end.Y - 1, 2, 2);
// 箭头长度
float arrowLength = 10 * scaleF;
// 箭头角度(V 型开口角度)
float arrowAngle = 30;
// 箭头朝向角度(相对于水平向右为 0 度)
float orientationAngle = drawLine.GetRotate();
// 将角度转换为弧度
float arrowAngleRadians = arrowAngle * (float)Math.PI / 180;
float orientationAngleRadians = orientationAngle * (float)Math.PI / 180;
// 尖角点位置
PointF tipPoint = center;
// 计算 V 型箭头的另外两个点
float halfAngle = arrowAngleRadians / 2;
PointF point1 = new PointF(
tipPoint.X - arrowLength * (float)Math.Cos(orientationAngleRadians - halfAngle),
tipPoint.Y - arrowLength * (float)Math.Sin(orientationAngleRadians - halfAngle)
);
PointF point2 = new PointF(
tipPoint.X - arrowLength * (float)Math.Cos(orientationAngleRadians + halfAngle),
tipPoint.Y - arrowLength * (float)Math.Sin(orientationAngleRadians + halfAngle)
);
//绘制尖角两条线形成指向箭头
e.Graphics.DrawLine(pen, tipPoint, point1);
e.Graphics.DrawLine(pen, tipPoint, point2);
}
PointF lineStart = ImageTransScreenPointF(drawLine.startPoint);
PointF lineEnd = ImageTransScreenPointF(drawLine.endPoint);
e.Graphics.DrawLine(pen, lineStart, lineEnd);
}
}
private void PaintRectangle(PaintEventArgs e)
{
using (Pen pen = new Pen(drawRectangle.penColor, drawRectangle.penSize))
{
using (Pen selectPen = new Pen(drawRectangle.isSelect ? drawRectangle.selectColor : drawRectangle.penColor, drawRectangle.penSize + 1))
{
//获取圆心像素坐标 转换成控件坐标
PointF center = ImageTransScreenPointF(drawRectangle.GetCenter());
//根据中心坐标拟合两条垂直线
// 绘制垂直的线(中心点上下各 3 像素)
e.Graphics.DrawLine(selectPen, center.X, center.Y - drawRectangle.GetCenterSize() * scaleF, center.X, center.Y + drawRectangle.GetCenterSize() * scaleF);
// 绘制水平的线(中心点左右各 3 像素)
e.Graphics.DrawLine(selectPen, center.X - drawRectangle.GetCenterSize() * scaleF, center.Y, center.X + drawRectangle.GetCenterSize() * scaleF, center.Y);
PointF br = ImageTransScreenPointF(drawRectangle.GetBR());
e.Graphics.DrawEllipse(selectPen, br.X - 1, br.Y - 1, 2, 2);
}
PointF rectTlLoca = ImageTransScreenPointF(drawRectangle.GetTL());
PointF rectBrLoca = ImageTransScreenPointF(drawRectangle.GetBR());
e.Graphics.DrawRectangle(pen, rectTlLoca.X, rectTlLoca.Y, rectBrLoca.X - rectTlLoca.X, rectBrLoca.Y - rectTlLoca.Y);
}
}
private void PaintCircle(PaintEventArgs e)
{
using (Pen pen = new Pen(drawCircle.penColor, drawCircle.penSize))
{
using (Pen selectPen = new Pen(drawCircle.isSelect ? drawCircle.selectColor : drawCircle.penColor, drawCircle.penSize + 1))
{
//绘制圆心小十字
//获取圆心像素坐标 转换成控件坐标
PointF center = ImageTransScreenPointF(drawCircle.center);
//根据中心坐标拟合两条垂直线
// 绘制垂直的线(中心点上下各 3 像素)
e.Graphics.DrawLine(selectPen, center.X, center.Y - drawCircle.GetCenterSize() * scaleF, center.X, center.Y + drawCircle.GetCenterSize() * scaleF);
// 绘制水平的线(中心点左右各 3 像素)
e.Graphics.DrawLine(selectPen, center.X - drawCircle.GetCenterSize() * scaleF, center.Y, center.X + drawCircle.GetCenterSize() * scaleF, center.Y);
PointF rightPoint = ImageTransScreenPointF(drawCircle.GetScalePoint());
//绘制拖动缩放点
e.Graphics.DrawEllipse(selectPen, rightPoint.X - 1, rightPoint.Y - 1, 2, 2);
}
//圆的中心坐标转控件坐标
PointF rectTL = ImageTransScreenPointF(drawCircle.GetRectTL());
PointF rectBR = ImageTransScreenPointF(drawCircle.GetRectBR());
SizeF size = new SizeF(rectBR.X - rectTL.X, rectBR.Y - rectTL.Y);
e.Graphics.DrawEllipse(pen, new RectangleF(rectTL, size));
}
}
private void PaintRotateRect(PaintEventArgs e)
{
using (Pen pen = new Pen(drawRotateRect.penColor, drawRotateRect.penSize))
{
//绘制矩形
PointF[] corners = drawRotateRect.GetCorners();
List<PointF> cornersScr = new List<PointF>();
for (int i = 0; i < corners.Length; i++)
{
cornersScr.Add(ImageTransScreenPointF(corners[i]));
}
e.Graphics.DrawPolygon(pen, cornersScr.ToArray());
using (Pen selectPen = new Pen(drawRotateRect.isSelect ? drawRotateRect.selectColor : drawRotateRect.penColor, drawRotateRect.penSize + 1))
{
//绘制圆心小十字
//获取圆心像素坐标 转换成控件坐标
PointF center = ImageTransScreenPointF(drawRotateRect.center);
//根据中心坐标拟合两条垂直线
// 绘制垂直的线(中心点上下各 3 像素)
e.Graphics.DrawLine(selectPen, center.X, center.Y - drawRotateRect.GetCenterSize() * scaleF, center.X, center.Y + drawRotateRect.GetCenterSize() * scaleF);
// 绘制水平的线(中心点左右各 3 像素)
e.Graphics.DrawLine(selectPen, center.X - drawRotateRect.GetCenterSize() * scaleF, center.Y, center.X + drawRotateRect.GetCenterSize() * scaleF, center.Y);
PointF tr = ImageTransScreenPointF(drawRotateRect.tr);
e.Graphics.DrawEllipse(selectPen, tr.X - 1, tr.Y - 1, 2, 2);
PointF rc = ImageTransScreenPointF(drawRotateRect.GetRightCenter());
e.Graphics.DrawEllipse(selectPen, rc.X - 1, rc.Y - 1, 2, 2);
PointF bc = ImageTransScreenPointF(drawRotateRect.GetBottomCenter());
e.Graphics.DrawEllipse(selectPen, bc.X - 1, bc.Y - 1, 2, 2);
}
}
}
private void PaintPolygon(PaintEventArgs e)
{
using (Pen pen = new Pen(penColor, penSize))
{
//绘制路径
List<PointF> ps = ImageTransScreenPointF(drawPolygon.polygonPath);
if (drawPolygon.polygonPath.Count >= 2)
{
e.Graphics.DrawLines(pen, ps.ToArray());
}
using (Pen selectPen = new Pen(drawPolygon.isSelect ? drawPolygon.selectColor : drawPolygon.penColor, drawPolygon.penSize + 1))
{
//绘制中心小十字
//获取圆心像素坐标 转换成控件坐标
PointF center = ImageTransScreenPointF(drawPolygon.GetCenter());
//根据中心坐标拟合两条垂直线
// 绘制垂直的线(中心点上下各 3 像素)
e.Graphics.DrawLine(selectPen, center.X, center.Y - drawPolygon.GetCenterSize() * scaleF, center.X, center.Y + drawPolygon.GetCenterSize() * scaleF);
// 绘制水平的线(中心点左右各 3 像素)
e.Graphics.DrawLine(selectPen, center.X - drawPolygon.GetCenterSize() * scaleF, center.Y, center.X + drawPolygon.GetCenterSize() * scaleF, center.Y);
foreach (PointF p in ps)
{
//绘制拖动缩放点
e.Graphics.DrawEllipse(selectPen, p.X - 1, p.Y - 1, 2, 2);
}
}
}
}
/// <summary>
/// 控件重绘
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void mainView_Paint(object sender, PaintEventArgs e)
{
sw.Restart();
if (imageBmp != null)
{
// 计算缩放后的图片大小
int newWidth = (int)(imageBmp.Width * scaleF);
int newHeight = (int)(imageBmp.Height * scaleF);
// 判断显示模式设置绘制质量
if (viewMode == DisplayMode.Pixel)
{
e.Graphics.SmoothingMode = SmoothingMode.None;
e.Graphics.InterpolationMode = InterpolationMode.NearestNeighbor;
e.Graphics.PixelOffsetMode = PixelOffsetMode.HighQuality;
e.Graphics.CompositingQuality = CompositingQuality.HighQuality;
}
else
{
e.Graphics.SmoothingMode = SmoothingMode.HighQuality;
e.Graphics.InterpolationMode = InterpolationMode.HighQualityBicubic;
e.Graphics.PixelOffsetMode = PixelOffsetMode.HighQuality;
e.Graphics.CompositingQuality = CompositingQuality.HighQuality;
e.Graphics.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAliasGridFit;
}
// 绘制缩放后的图片
e.Graphics.DrawImage(imageBmp, offset.X, offset.Y, newWidth, newHeight);
//更新缩放率
toolStripSplitButton_scale.Text = $"{(scaleF * 100).ToString("0")}%";
if (drawPoint != null)
{
PaintPoint(e);
}
if (drawLine != null)
{
PaintLine(e);
}
if (drawCircle != null)
{
PaintCircle(e);
}
if (drawEllipse != null)
{
}
if (drawRectangle != null)
{
PaintRectangle(e);
}
if (drawRotateRect != null)
{
PaintRotateRect(e);
}
if (drawPolygon != null && drawPolygon.polygonPath.Count > 0)
{
PaintPolygon(e);
}
}
sw.Stop();
if (sw.ElapsedMilliseconds > 0)
{
Console.WriteLine("重绘耗时ms:" + sw.ElapsedMilliseconds + " fps:" + 1000 / sw.ElapsedMilliseconds);
}
}
private void mainView_MouseDown(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left && mainView.Cursor == Cursors.Hand)
{
startMovePosition = e.Location;
}
if (e.Button == MouseButtons.Right && operatorMode == DrawMode.None && drawState == DrawState.Done)
{
contextMenuStrip_menu.Show(mainView, e.Location);
Point testPoint = ImageTransScreenPoint(new Point(0, 0));
Console.WriteLine($" Sx:{testPoint.X} Sy:{testPoint.Y}");
}
switch (operatorMode)
{
case DrawMode.Point:
DrawPoint(e);
break;
case DrawMode.Line:
DrawLine(e);
break;
case DrawMode.Rectangle:
DrawRectangle(e);
break;
case DrawMode.RotateRect:
DrawRotateRect(e);
break;
case DrawMode.Circle:
DrawCircle(e);
break;
case DrawMode.Polygon:
DrawPolygon(e);
break;
}
mainView.Invalidate();
}
private bool IsCanSelect(PointF center, Point mouse, float relative)
{
PointF screenCenter = ImageTransScreenPointF(center);
if (Math.Abs(mouse.X - screenCenter.X) <= relative && Math.Abs(mouse.Y - screenCenter.Y) <= relative)
{
return true;
}
else
{
return false;
}
}
private void contextMenuStrip_menu_ItemClicked(object sender, ToolStripItemClickedEventArgs e)
{
this.contextMenuStrip_menu.Close();
string clickedItemText = e.ClickedItem.Text;
Console.WriteLine(clickedItemText);
switch (clickedItemText)
{
case "导入图像":
this.ImportImage();
break;
case "自适应":
this.Fit();
break;
case "水平翻转":
this.FlipX();
break;
case "垂直翻转":
this.FlipY();
break;
case "顺时针旋转":
this.RightRotate();
break;
case "逆时针旋转":
this.LeftRotate();
break;
case "恢复":
this.Restore();
break;
case "像素级":
viewMode = DisplayMode.Pixel;
mainView.Invalidate();
break;
case "高质量":
viewMode = DisplayMode.HighQuality;
mainView.Invalidate();
break;
case "Point":
Console.WriteLine("画一个点");
StartDrawPoint();
break;
case "Line":
Console.WriteLine("画一条线");
StartDrawLine();
break;
case "Rectangle":
Console.WriteLine("画一个矩形");
StartDrawRectangle();
break;
case "RotateRect":
Console.WriteLine("画一个旋转矩形");
StartDrawRotateRect();
break;
case "Circle":
Console.WriteLine("画一个圆形");
StartDrawCircle();
break;
case "Eclipse":
Console.WriteLine("画一个椭圆");
break;
case "Polygon":
Console.WriteLine("画多边形");
StartDrawPolygon();
break;
case "1":
Console.WriteLine("设置宽度1");
penSize = 1;
break;
case "2":
Console.WriteLine("设置宽度2");
penSize = 2;
break;
case "3":
Console.WriteLine("设置宽度3");
penSize = 3;
break;
case "4":
Console.WriteLine("设置宽度4");
penSize = 4;
break;
case "5":
Console.WriteLine("设置宽度5");
penSize = 5;
break;
case "Black":
Console.WriteLine("设置黑色");
penColor = Color.Black;
break;
case "White":
Console.WriteLine("设置白色");
penColor = Color.White;
break;
case "Red":
Console.WriteLine("设置红色");
penColor = Color.Red;
break;
case "Green":
Console.WriteLine("设置绿色");
penColor = Color.Green;
break;
case "Blue":
Console.WriteLine("设置蓝色");
penColor = Color.Blue;
break;
case "Yellow":
Console.WriteLine("设置黄色");
penColor = Color.Yellow;
break;
case "移除图像":
Console.WriteLine("移除图像");
this.RemoveImage();
break;
case "保存图像":
Console.WriteLine("保存图像");
this.SaveImage();
break;
default:
break;
}
}
private void mainView_Resize(object sender, EventArgs e)
{
if (imageBmp != null)
{
// 计算初始的缩放比例和偏移量
}
}
#region 操作封装
private void ClearDraw()
{
if (operatorMode == DrawMode.None && drawState == DrawState.Done)
{
drawPoint = null;
drawLine = null;
drawRectangle = null;
drawRotateRect = null;
drawCircle = null;
drawPolygon = null;
mainView.Invalidate();
}
}
private void StartDrawPoint()
{
if (imageBmp != null)
{
drawPoint = new DrawPoint();
drawPoint.penColor = penColor;
drawPoint.penSize = penSize;
operatorMode = DrawMode.Point;
drawState = DrawState.Start;
mainView.Cursor = Cursors.Cross;
}
}
private void DrawPoint(MouseEventArgs e)
{
switch (drawState)
{
case DrawState.Start:
if (e.Button == MouseButtons.Left && IsMouseOnImage(e.Location))
{
drawPoint.point = ScreenTransImagePointF(e.Location);
drawState = DrawState.Drawing;
}
break;
case DrawState.Drawing:
//更新点的位置
if (e.Button == MouseButtons.Left && IsMouseOnImage(e.Location))
{
drawPoint.point = ScreenTransImagePointF(e.Location);
}
break;
}
}
private void StartDrawLine()
{
if (imageBmp != null)
{
drawLine = new DrawLine();
drawLine.penColor = penColor;
drawLine.penSize = penSize;
operatorMode = DrawMode.Line;
drawState = DrawState.Start;
mainView.Cursor = Cursors.Cross;
}
}
private void DrawLine(MouseEventArgs e)
{
switch (drawState)
{
case DrawState.Start:
if (e.Button == MouseButtons.Left && IsMouseOnImage(e.Location))
{
drawLine.startPoint = ScreenTransImagePointF(e.Location);
drawLine.endPoint = ScreenTransImagePointF(e.Location);
drawState = DrawState.Drawing;
}
break;
case DrawState.Drawing:
if (e.Button == MouseButtons.Left && IsMouseOnImage(e.Location))
{
drawLine.endPoint = ScreenTransImagePointF(e.Location);
}
else if (e.Button != MouseButtons.Left && IsMouseOnImage(e.Location))
{
drawState = DrawState.Finish;
}
break;
case DrawState.Finish:
if (IsMouseOnImage(e.Location) && IsCanSelect(drawLine.GetCenter(), e.Location, 5) ||
IsCanSelect(drawLine.startPoint, e.Location, 5) || IsCanSelect(drawLine.endPoint, e.Location, 5))
{
mainView.Cursor = Cursors.SizeAll;
drawLine.isSelect = true;
}
else
{
mainView.Cursor = Cursors.Cross;
drawLine.isSelect = false;
}
if (e.Button == MouseButtons.Left && IsMouseOnImage(e.Location) && IsCanSelect(drawLine.GetCenter(), e.Location, 5))
{
drawState = DrawState.Moving;
}
else if (e.Button == MouseButtons.Left && IsMouseOnImage(e.Location) && IsCanSelect(drawLine.startPoint, e.Location, 5))
{
drawState = DrawState.StartDraging;
}
else if (e.Button == MouseButtons.Left && IsMouseOnImage(e.Location) && IsCanSelect(drawLine.endPoint, e.Location, 5))
{
drawState = DrawState.EndDraging;
}
else if (e.Button == MouseButtons.Left && IsMouseOnImage(e.Location) && !IsCanSelect(drawLine.GetCenter(), e.Location, 5))
{
drawState = DrawState.Start;
}
break;
case DrawState.Moving:
if (e.Button == MouseButtons.Left && IsMouseOnImage(e.Location))
{
float relativeX = ScreenTransImagePointF(e.Location).X - drawLine.GetCenter().X;
float relativeY = ScreenTransImagePointF(e.Location).Y - drawLine.GetCenter().Y;
//更新坐标
drawLine.startPoint.X += relativeX;
drawLine.startPoint.Y += relativeY;
drawLine.endPoint.X += relativeX;
drawLine.endPoint.Y += relativeY;
}
else if (e.Button != MouseButtons.Left && IsMouseOnImage(e.Location))
{
drawState = DrawState.Finish;
}
break;
case DrawState.StartDraging:
if (e.Button == MouseButtons.Left && IsMouseOnImage(e.Location))
{
//更新起点坐标
drawLine.startPoint = ScreenTransImagePointF(e.Location);
}
else if (e.Button != MouseButtons.Left && IsMouseOnImage(e.Location))
{
drawState = DrawState.Finish;
}
break;
case DrawState.EndDraging:
if (e.Button == MouseButtons.Left && IsMouseOnImage(e.Location))
{
//更新终点坐标
drawLine.endPoint = ScreenTransImagePointF(e.Location);
}
else if (e.Button != MouseButtons.Left && IsMouseOnImage(e.Location))
{
drawState = DrawState.Finish;
}
break;
}
}
private void StartDrawRectangle()
{
if (imageBmp != null)
{
drawRectangle = new DrawRectangle();
drawRectangle.penColor = penColor;
drawRectangle.penSize = penSize;
operatorMode = DrawMode.Rectangle;
drawState = DrawState.Start;
mainView.Cursor = Cursors.Cross;
}
}
private void DrawRectangle(MouseEventArgs e)
{
switch (drawState)
{
case DrawState.Start:
if (e.Button == MouseButtons.Left && IsMouseOnImage(e.Location))
{
drawRectangle.rect.Location = ScreenTransImagePointF(e.Location);
drawState = DrawState.Drawing;
}
break;
case DrawState.Drawing:
if (e.Button == MouseButtons.Left && IsMouseOnImage(e.Location))
{
PointF rbLoca = ScreenTransImagePointF(e.Location);
drawRectangle.rect.Width = Math.Abs(rbLoca.X - drawRectangle.rect.X);
drawRectangle.rect.Height = Math.Abs(rbLoca.Y - drawRectangle.rect.Y);
}
else if (e.Button != MouseButtons.Left && IsMouseOnImage(e.Location))
{
drawState = DrawState.Finish;
}
break;
case DrawState.Finish:
//显示
if (IsMouseOnImage(e.Location) && IsCanSelect(drawRectangle.GetCenter(), e.Location, 5))
{
mainView.Cursor = Cursors.SizeAll;
drawRectangle.isSelect = true;
}
else if (IsMouseOnImage(e.Location) && IsCanSelect(drawRectangle.GetBR(), e.Location, 5))
{
mainView.Cursor = Cursors.SizeNWSE;
drawRectangle.isSelect = true;
}
else
{
mainView.Cursor = Cursors.Cross;
drawRectangle.isSelect = false;
}
//操作
if (e.Button == MouseButtons.Left && IsMouseOnImage(e.Location) && IsCanSelect(drawRectangle.GetCenter(), e.Location, 5))
{
drawState = DrawState.Moving;
}
else if (e.Button == MouseButtons.Left && IsMouseOnImage(e.Location) && IsCanSelect(drawRectangle.GetBR(), e.Location, 5))
{
drawState = DrawState.BrDraging;
}
else if (e.Button == MouseButtons.Left && !IsCanSelect(drawRectangle.GetCenter(), e.Location, 5) && !IsCanSelect(drawRectangle.GetBR(), e.Location, 5))
{
drawState = DrawState.Start;
}
break;
case DrawState.Moving:
if (e.Button == MouseButtons.Left && IsMouseOnImage(e.Location))
{
//更新坐标
drawRectangle.rect.X = ScreenTransImagePointF(e.Location).X - drawRectangle.rect.Width / 2;
drawRectangle.rect.Y = ScreenTransImagePointF(e.Location).Y - drawRectangle.rect.Height / 2;
}
else if (e.Button != MouseButtons.Left && IsMouseOnImage(e.Location))
{
drawState = DrawState.Finish;
}
break;
case DrawState.BrDraging:
if (e.Button == MouseButtons.Left && IsMouseOnImage(e.Location))
{
//更新宽高
PointF mouse = ScreenTransImagePointF(e.Location);
drawRectangle.rect.Width = Math.Abs(mouse.X - drawRectangle.rect.X);
drawRectangle.rect.Height = Math.Abs(mouse.Y - drawRectangle.rect.Y);
}
else if (e.Button != MouseButtons.Left && IsMouseOnImage(e.Location))
{
drawState = DrawState.Finish;
}
break;
}
}
private void StartDrawEllipse()
{
if (imageBmp != null)
{
drawEllipse = new DrawEllipse();
drawEllipse.penColor = penColor;
drawEllipse.penSize = penSize;
operatorMode = DrawMode.Ellipse;
drawState = DrawState.Start;
mainView.Cursor = Cursors.Cross;
}
}
private void DrawEllipse(MouseEventArgs e)
{
switch (drawState)
{
case DrawState.Start:
break;
case DrawState.Drawing:
break;
case DrawState.Finish:
break;
case DrawState.Moving:
break;
}
}
/// <summary>
/// 开始绘制圆
/// </summary>
private void StartDrawCircle()
{
if (imageBmp != null)
{
drawCircle = new DrawCircle();
drawCircle.penColor = penColor;
drawCircle.penSize = penSize;
operatorMode = DrawMode.Circle;
drawState = DrawState.Start;
mainView.Cursor = Cursors.Cross;
}
}
private void DrawCircle(MouseEventArgs e)
{
switch (drawState)
{
case DrawState.Start:
if (e.Button == MouseButtons.Left && IsMouseOnImage(e.Location))
{
drawCircle.center = ScreenTransImagePointF(e.Location);
drawState = DrawState.Drawing;
}
break;
case DrawState.Drawing:
if (e.Button == MouseButtons.Left && IsMouseOnImage(e.Location))
{
PointF movePoint = ScreenTransImagePointF(e.Location);
//计算圆半径
drawCircle.radius = (float)Math.Sqrt(Math.Pow(Math.Abs(movePoint.X - drawCircle.center.X), 2) + Math.Pow(Math.Abs(movePoint.Y - drawCircle.center.Y), 2));
}
else if (e.Button != MouseButtons.Left && IsMouseOnImage(e.Location))
{
drawState = DrawState.Finish;
}
break;
case DrawState.Finish:
if (IsMouseOnImage(e.Location) && IsCanSelect(drawCircle.center, e.Location, 5))
{
mainView.Cursor = Cursors.SizeAll;
drawCircle.isSelect = true;
}
else if (IsMouseOnImage(e.Location) && IsCanSelect(drawCircle.GetScalePoint(), e.Location, 5))
{
mainView.Cursor = Cursors.SizeWE;
drawCircle.isSelect = true;
}
else
{
mainView.Cursor = Cursors.Cross;
drawCircle.isSelect = false;
}
//更新
if (e.Button == MouseButtons.Left && IsMouseOnImage(e.Location) && IsCanSelect(drawCircle.center, e.Location, 5))
{
drawState = DrawState.Moving;
}
else if (e.Button == MouseButtons.Left && IsMouseOnImage(e.Location) && IsCanSelect(drawCircle.GetScalePoint(), e.Location, 5))
{
drawState = DrawState.ScaleDraging;
}
else if (e.Button == MouseButtons.Left && IsMouseOnImage(e.Location) && !IsCanSelect(drawCircle.center, e.Location, 5))
{
drawState = DrawState.Start;
}
break;
case DrawState.Moving:
if (e.Button == MouseButtons.Left && IsMouseOnImage(e.Location))
{
//更新坐标
drawCircle.center = ScreenTransImagePointF(e.Location);
}
else if (e.Button != MouseButtons.Left && IsMouseOnImage(e.Location))
{
drawState = DrawState.Finish;
}
break;
case DrawState.ScaleDraging:
if (e.Button == MouseButtons.Left && IsMouseOnImage(e.Location))
{
//更新半径
drawCircle.radius = ScreenTransImagePointF(e.Location).X - drawCircle.center.X;
}
else if (e.Button != MouseButtons.Left && IsMouseOnImage(e.Location))
{
drawState = DrawState.Finish;
}
break;
}
}
private void StartDrawRotateRect()
{
if (imageBmp != null)
{
drawRotateRect = new DrawRotateRect();
drawRotateRect.penColor = penColor;
drawRotateRect.penSize = penSize;
operatorMode = DrawMode.RotateRect;
drawState = DrawState.Start;
mainView.Cursor = Cursors.Cross;
}
}
private void DrawRotateRect(MouseEventArgs e)
{
switch (drawState)
{
case DrawState.Start:
if (e.Button == MouseButtons.Left && IsMouseOnImage(e.Location))
{
drawRotateRect.center = ScreenTransImagePointF(e.Location);
drawState = DrawState.Drawing;
}
break;
case DrawState.Drawing:
if (e.Button == MouseButtons.Left && IsMouseOnImage(e.Location))
{
float w = ScreenTransImagePointF(e.Location).X - drawRotateRect.center.X;
float h = ScreenTransImagePointF(e.Location).Y - drawRotateRect.center.Y;
drawRotateRect.widthHalf = w;
drawRotateRect.heightHalf = h;
}
else if (e.Button != MouseButtons.Left && IsMouseOnImage(e.Location))
{
drawState = DrawState.Finish;
}
break;
case DrawState.Finish:
//显示
if (IsMouseOnImage(e.Location) && IsCanSelect(drawRotateRect.center, e.Location, 5))
{
mainView.Cursor = Cursors.SizeAll;
drawRotateRect.isSelect = true;
}
else if (IsMouseOnImage(e.Location) && IsCanSelect(drawRotateRect.tr, e.Location, 10))
{
mainView.Cursor = rotateCursor;
drawRotateRect.isSelect = true;
}
else if (IsMouseOnImage(e.Location) && IsCanSelect(drawRotateRect.GetRightCenter(), e.Location, 5))
{
mainView.Cursor = Cursors.SizeWE;
drawRotateRect.isSelect = true;
}
else if (IsMouseOnImage(e.Location) && IsCanSelect(drawRotateRect.GetBottomCenter(), e.Location, 5))
{
mainView.Cursor = Cursors.SizeNS;
drawRotateRect.isSelect = true;
}
else
{
mainView.Cursor = Cursors.Cross;
drawRotateRect.isSelect = false;
}
//操作
if (e.Button == MouseButtons.Left && IsMouseOnImage(e.Location) && IsCanSelect(drawRotateRect.center, e.Location, 5))
{
drawState = DrawState.Moving;
}
else if (e.Button == MouseButtons.Left && IsMouseOnImage(e.Location) && IsCanSelect(drawRotateRect.tr, e.Location, 10))
{
drawState = DrawState.Rotate;
}
else if (e.Button == MouseButtons.Left && IsCanSelect(drawRotateRect.GetRightCenter(), e.Location, 5))
{
drawState = DrawState.RightDraging;
}
else if (e.Button == MouseButtons.Left && IsCanSelect(drawRotateRect.GetBottomCenter(), e.Location, 5))
{
drawState = DrawState.BottomDraging;
}
else if (e.Button == MouseButtons.Left && !IsCanSelect(drawRotateRect.center, e.Location, 5) && !IsCanSelect(drawRotateRect.tr, e.Location, 5))
{
drawState = DrawState.Start;
}
break;
case DrawState.Moving:
if (e.Button == MouseButtons.Left && IsMouseOnImage(e.Location))
{
//更新坐标
PointF newP = ScreenTransImagePointF(e.Location);
drawRotateRect.MoveCenrer(newP);
}
else if (e.Button != MouseButtons.Left && IsMouseOnImage(e.Location))
{
drawState = DrawState.Finish;
}
break;
case DrawState.Rotate:
if (e.Button == MouseButtons.Left && IsMouseOnImage(e.Location))
{
//计算角度
PointF mouse = ScreenTransImagePointF(e.Location);
//计算中心与右上角角度
double r = ShapeTools.GetRotate(drawRotateRect.center, drawRotateRect.tr);
//计算鼠标与中心的角度
double mr = ShapeTools.GetRotate(drawRotateRect.center, mouse);
//角点旋转
drawRotateRect.Rotate(mr - r);
//获取左边与右边中点 计算矩形当前角度
drawRotateRect.rotate = ShapeTools.GetRotate(drawRotateRect.GetLeftCenter(), drawRotateRect.GetRightCenter());
if (Math.Abs(drawRotateRect.rotate) > 0 && Math.Abs(drawRotateRect.rotate) < 1)
{
drawRotateRect.Rotate(0 - drawRotateRect.rotate);
drawRotateRect.rotate += 0 - drawRotateRect.rotate;
}
Console.WriteLine(drawRotateRect.rotate);
}
else if (e.Button != MouseButtons.Left && IsMouseOnImage(e.Location))
{
drawState = DrawState.Finish;
}
break;
case DrawState.RightDraging:
if (e.Button == MouseButtons.Left && IsMouseOnImage(e.Location))
{
float w = ScreenTransImagePointF(e.Location).X - drawRotateRect.center.X;
drawRotateRect.widthHalf = w;
}
else if (e.Button != MouseButtons.Left && IsMouseOnImage(e.Location))
{
drawState = DrawState.Finish;
}
break;
case DrawState.BottomDraging:
if (e.Button == MouseButtons.Left && IsMouseOnImage(e.Location))
{
float h = ScreenTransImagePointF(e.Location).Y - drawRotateRect.center.Y;
drawRotateRect.heightHalf = h;
}
else if (e.Button != MouseButtons.Left && IsMouseOnImage(e.Location))
{
drawState = DrawState.Finish;
}
break;
}
}
/// <summary>
/// 开始绘制多边形
/// </summary>
private void StartDrawPolygon()
{
if (imageBmp != null)
{
drawPolygon = new DrawPolygon();
drawPolygon.penColor = penColor;
drawPolygon.penSize = penSize;
operatorMode = DrawMode.Polygon;
drawState = DrawState.Start;
mainView.Cursor = Cursors.Cross;
}
}
/// <summary>
/// 绘制多边形
/// </summary>
/// <param name="e"></param>
private void DrawPolygon(MouseEventArgs e)
{
switch (drawState)
{
case DrawState.Start:
if (e.Button == MouseButtons.Left && IsMouseOnImage(e.Location))
{
if (drawPolygon.polygonPath.Count > 1)
{
drawPolygon.polygonPath.Clear();
}
//添加起点
drawPolygon.polygonPath.Add(ScreenTransImagePointF(e.Location));
drawState = DrawState.Drawing;
}
break;
case DrawState.Drawing:
if (IsMouseOnImage(e.Location) && IsCanSelect(drawPolygon.polygonPath[0], e.Location, 5))
{
mainView.Cursor = Cursors.Hand;
}
else
{
mainView.Cursor = Cursors.Cross;
}
if (e.Button == MouseButtons.Left && IsMouseOnImage(e.Location) && !IsCanSelect(drawPolygon.polygonPath[0], e.Location, 5))
{
//添加路径
drawPolygon.polygonPath.Add(ScreenTransImagePointF(e.Location));
}
else if (e.Button == MouseButtons.Left && IsMouseOnImage(e.Location) && IsCanSelect(drawPolygon.GetCenter(), e.Location, 5))
{
drawState = DrawState.Moving;
}
else if (e.Button == MouseButtons.Left && IsMouseOnImage(e.Location) && IsCanSelect(drawPolygon.polygonPath[0], e.Location, 5))
{
PointF start = drawPolygon.polygonPath[0];
drawPolygon.polygonPath.Add(start);
drawState = DrawState.Finish;
}
break;
case DrawState.Finish:
if (IsMouseOnImage(e.Location) && IsCanSelect(drawPolygon.GetCenter(), e.Location, 5))
{
mainView.Cursor = Cursors.SizeAll;
drawPolygon.isSelect = true;
}
else
{
mainView.Cursor = Cursors.Cross;
drawPolygon.isSelect = false;
}
if (e.Button == MouseButtons.Left && IsMouseOnImage(e.Location) && IsCanSelect(drawPolygon.GetCenter(), e.Location, 5))
{
drawState = DrawState.Moving;
}
else if (e.Button == MouseButtons.Left && IsMouseOnImage(e.Location) && !IsCanSelect(drawPolygon.polygonPath[0], e.Location, 5))
{
drawState = DrawState.Start;
}
break;
case DrawState.Moving:
if (e.Button == MouseButtons.Left && IsMouseOnImage(e.Location))
{
//更新坐标
drawPolygon.ChangeAllPath(ScreenTransImagePointF(e.Location));
}
else if (e.Button != MouseButtons.Left && IsMouseOnImage(e.Location))
{
drawState = DrawState.Finish;
}
break;
}
}
/// <summary>
/// 结束绘制
/// </summary>
private void DrawEnd()
{
operatorMode = DrawMode.None;
drawState = DrawState.Done;
mainView.Cursor = Cursors.Default;
}
private void FlipX()
{
if (imageBmp != null)
{
imageBmp.RotateFlip(RotateFlipType.RotateNoneFlipX);
this.Fit();
}
}
private void FlipY()
{
if (imageBmp != null)
{
imageBmp.RotateFlip(RotateFlipType.RotateNoneFlipY);
this.Fit();
}
}
private void LeftRotate()
{
if (imageBmp != null)
{
imageBmp.RotateFlip(RotateFlipType.Rotate270FlipNone);
this.Fit();
}
}
private void RightRotate()
{
if (imageBmp != null)
{
imageBmp.RotateFlip(RotateFlipType.Rotate90FlipNone);
this.Fit();
}
}
private void Restore()
{
if (cloneBmp != null)
{
imageBmp = cloneBmp.Clone() as Bitmap;
this.Fit();
}
}
#endregion
private void toolStripButton_clear_Click(object sender, EventArgs e)
{
this.ClearDraw();
}
/// <summary>
/// 鼠标样式切换到箭头
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void toolStripButton_arrow_Click(object sender, EventArgs e)
{
if (operatorMode == DrawMode.None)
{
mainView.Cursor = Cursors.Arrow;
}
}
/// <summary>
/// 鼠标样式切换到抓手
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void toolStripButton_hand_Click(object sender, EventArgs e)
{
if (operatorMode == DrawMode.None)
{
mainView.Cursor = Cursors.Hand;
}
}
/// <summary>
/// 自适应显示
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void toolStripButton_fit_Click(object sender, EventArgs e)
{
this.Fit();
}
/// <summary>
/// 缩放选项点击事件
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void toolStripSplitButton_scale_DropDownItemClicked(object sender, ToolStripItemClickedEventArgs e)
{
if (imageBmp == null) { return; }
float oldScale = scaleF;
switch (e.ClickedItem.Text)
{
case "50%":
scaleF = 0.5f;
break;
case "100%":
scaleF = 1f;
break;
case "150%":
scaleF = 1.5f;
break;
case "200%":
scaleF = 2f;
break;
}
float dx = mainView.Width / 2 - offset.X;
float dy = mainView.Height / 2 - offset.Y;
offset.X -= dx * (scaleF / oldScale - 1);
offset.Y -= dy * (scaleF / oldScale - 1);
mainView.Invalidate();
}
private void toolStripButton_leftRotate_Click(object sender, EventArgs e)
{
LeftRotate();
}
private void toolStripButton_rightRotate_Click(object sender, EventArgs e)
{
RightRotate();
}
private void toolStripMenuItem_point_Click(object sender, EventArgs e)
{
StartDrawPoint();
}
private void toolStripMenuItem_line_Click(object sender, EventArgs e)
{
StartDrawLine();
}
private void toolStripMenuItem_rectangle_Click(object sender, EventArgs e)
{
StartDrawRectangle();
}
private void toolStripMenuItem_circle_Click(object sender, EventArgs e)
{
StartDrawCircle();
}
private void mainView_MouseClick(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Right && drawState != DrawState.Done)
{
switch (operatorMode)
{
case DrawMode.Point:
drawPoint.isSelect = false;
Console.WriteLine($"Point X:{(int)drawPoint.point.X} Y:{(int)drawPoint.point.Y}");
break;
case DrawMode.Line:
drawLine.isSelect = false;
Console.WriteLine($"Line sX:{drawLine.startPoint.X} sY:{drawLine.startPoint.Y} --- eX:{drawLine.endPoint.X} eY:{drawLine.endPoint.Y}");
break;
case DrawMode.Circle:
drawCircle.isSelect = false;
// 计算在图片上的位置
Console.WriteLine($"Circle X:{drawCircle.center.X} Y:{drawCircle.center.Y} --- R:{drawCircle.radius}");
break;
case DrawMode.Rectangle:
drawRectangle.isSelect = false;
Console.WriteLine($"Rectangle X:{drawRectangle.rect.X} Y:{drawRectangle.rect.Y} --- width:{drawRectangle.GetSize().Width} height:{drawRectangle.GetSize().Height}");
break;
case DrawMode.RotateRect:
drawRotateRect.isSelect = false;
Console.WriteLine($"RotateRect cX:{drawRotateRect.center.X} cY:{drawRotateRect.center.Y} --- width:{drawRotateRect.widthHalf} height:{drawRotateRect.heightHalf} rotate:{drawRotateRect.rotate}");
break;
case DrawMode.Polygon:
drawPolygon.isSelect = false;
break;
}
this.DrawEnd();
}
}
private void toolStripMenuItem_polygon_Click(object sender, EventArgs e)
{
StartDrawPolygon();
}
private void toolStripMenuItem_rotateRect_Click(object sender, EventArgs e)
{
StartDrawRotateRect();
}
public DrawPoint GetDrawPoint()
{
return drawPoint;
}
public DrawLine GetDrawLine()
{
return drawLine;
}
public DrawCircle GetDrawCircle()
{
return drawCircle;
}
public DrawRectangle GetDrawRectangle()
{
return drawRectangle;
}
public DrawRotateRect GetRotateRect()
{
return drawRotateRect;
}
public DrawPolygon GetDrawPolygon()
{
return drawPolygon;
}
private void mainView_SizeChanged(object sender, EventArgs e)
{
this.Fit();
}
}
}
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。