using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace Py_picture
{
public partial class Form1 : Form
{
List<Point> points;
int index;
bool draw = false;
float scale = 1.0f;
Point lastPoint;
bool pic_size_change = false; //判断图片是否缩放
bool isMoving = false; // 用于跟踪是否在移动多边形
Point offset; // 存储鼠标点击时的偏移量
public Form1()
{
InitializeComponent();
points = new List<Point>();
}
private void Form1_Load(object sender, EventArgs e)
{
pictureBox1.MouseWheel += pictureBox1_MouseWheel;
}
#region 按钮事件
private void button1_Click(object sender, EventArgs e)
{
//选择文件夹,选择图片
OpenFileDialog ofd = new OpenFileDialog();
ofd.Filter = "|*.bmp";
DialogResult = ofd.ShowDialog();
if (DialogResult == DialogResult.OK)
{
string pic = ofd.FileName;
//图片自适应大小
pictureBox1.SizeMode = PictureBoxSizeMode.Zoom;
//展示图片
pictureBox1.Image = Image.FromFile(pic);
textBox1.Text = pic;
// 重新绘制以适应新图像
pictureBox1.Invalidate();
pic_size_change = false; // 重置缩放状态
//pictureBox1.Invalidate();
}
}
private void button2_Click(object sender, EventArgs e)
{
// 检查是否进行了缩放
if (pictureBox1.Image==null)
{
MessageBox.Show("请先选择图片后,再进行绘制多边形", "提示", MessageBoxButtons.OK, MessageBoxIcon.Warning);
return;
}
else if (pictureBox1.Image != null&& !pic_size_change)
{
MessageBox.Show("请使用鼠标滚轮,调整好图片后再进行多边形的绘制!", "提示", MessageBoxButtons.OK, MessageBoxIcon.Warning);
return;
}
//开始绘制
draw = true;
}
private void button4_Click(object sender, EventArgs e)
{
//停止绘制
draw = false;
}
private void button3_Click(object sender, EventArgs e)
{
//清除绘制
points.Clear();
draw = false;
pictureBox1.Invalidate();
}
#endregion
#region picture鼠标事件
private void pictureBox1_MouseWheel(object sender, MouseEventArgs e)
{
float oldScale = scale;
// 记录缩放状态为 true
pic_size_change = true;
if (e.Delta > 0)
{
scale *= 1.1f; // 放大
}
else if (e.Delta < 0)
{
scale = Math.Max(0.14f, scale * 0.9f); //缩小,最小为0.14
}
if (pictureBox1.Image != null)
{
// 计算图像中心点
float centerX = (e.X - pictureBox1.Left) / oldScale; // 使用旧缩放比例
float centerY = (e.Y - pictureBox1.Top) / oldScale; // 使用旧缩放比例
// 更新 PictureBox 的宽高以反映新的缩放比例
pictureBox1.Width = (int)(pictureBox1.Image.Width * scale);
pictureBox1.Height = (int)(pictureBox1.Image.Height * scale);
// 确保中心点位置不变
int newX = (int)(centerX * scale);
int newY = (int)(centerY * scale);
pictureBox1.Left -= (newX - (e.X - pictureBox1.Left));
pictureBox1.Top -= (newY - (e.Y - pictureBox1.Top));
pictureBox1.Invalidate(); // 触发重绘
}
}
//private void pictureBox1_MouseDown(object sender, MouseEventArgs e)
//{
// // 计算点击点的缩放后坐标
// Point clickpoints = new Point((int)(e.X / scale), (int)(e.Y / scale));
// lastPoint = new Point(e.X, e.Y);
// pictureBox1.Cursor = Cursors.Hand;
// if (e.Button == MouseButtons.Left)
// {
// if (draw)
// {
// // 使用缩放后的坐标来添加点
// points.Add(clickpoints);
// pictureBox1.Invalidate();
// }
// }
// else if (e.Button == MouseButtons.Right)
// {
// index = GetPointIndex(clickpoints);
// if (index != -1)
// {
// pictureBox1.Capture = true;
// }
// }
//}
private void pictureBox1_MouseDown(object sender, MouseEventArgs e)
{
Point clickpoints = new Point((int)(e.X / scale), (int)(e.Y / scale));
lastPoint = new Point(e.X, e.Y);
pictureBox1.Cursor = Cursors.Hand;
if (e.Button == MouseButtons.Left)
{
if (draw)
{
points.Add(clickpoints);
pictureBox1.Invalidate();
}
else
{
index = GetPointIndex(clickpoints);
if (index != -1)
{
isMoving = true;
offset = new Point(clickpoints.X - points[index].X, clickpoints.Y - points[index].Y);
}
}
}
else if (e.Button == MouseButtons.Right)
{
index = GetPointIndex(clickpoints);
if (index != -1)
{
pictureBox1.Capture = true;
}
}
}
private void pictureBox1_MouseMove(object sender, MouseEventArgs e)
{
if (isMoving)
{
// 更新所有点的位置
for (int i = 0; i < points.Count; i++)
{
points[i] = new Point(
(int)Math.Round(points[i].X + (e.X - lastPoint.X) / scale),
(int)Math.Round(points[i].Y + (e.Y - lastPoint.Y) / scale)
);
}
pictureBox1.Invalidate(); // 触发重绘
}
else if (index != -1 && pictureBox1.Capture)
{
points[index] = new Point((int)(e.X / scale), (int)(e.Y / scale));
pictureBox1.Invalidate();
}
if (e.Button == MouseButtons.Left)
{
int deltaX = e.X - lastPoint.X;
int deltaY = e.Y - lastPoint.Y;
pictureBox1.Location = new Point(pictureBox1.Left + deltaX, pictureBox1.Top + deltaY);
}
lastPoint = e.Location; // 更新最后一个点
}
//private void pictureBox1_MouseMove(object sender, MouseEventArgs e)
//{
// if (index != -1 && pictureBox1.Capture)
// {
// // 更新点的位置,但仍然使用原始坐标
// points[index] = new Point((int)(e.X / scale), (int)(e.Y / scale));
// pictureBox1.Invalidate();
// }
// if (e.Button == MouseButtons.Left)
// {
// int deltaX = e.X - lastPoint.X;
// int deltaY = e.Y - lastPoint.Y;
// pictureBox1.Location = new Point(pictureBox1.Left + deltaX, pictureBox1.Top + deltaY);
// }
// lastPoint = e.Location; // 更新最后一个点
//}
//private void pictureBox1_MouseUp(object sender, MouseEventArgs e)
//{
// pictureBox1.Cursor = Cursors.Default;
// // 释放鼠标捕获
// pictureBox1.Capture = false;
// index = -1; // 重置选中点索引
//}
private void pictureBox1_MouseUp(object sender, MouseEventArgs e)
{
pictureBox1.Cursor = Cursors.Default;
pictureBox1.Capture = false;
index = -1; // 重置选中点索引
isMoving = false; // 重置移动状态
}
private void pictureBox1_Paint(object sender, PaintEventArgs e)
{
// 在窗体上绘制所有存储的点
foreach (Point p in points)
{
// 绘制小圆点,考虑缩放
Point scaledPoint = new Point((int)(p.X * scale), (int)(p.Y * scale));
e.Graphics.FillEllipse(Brushes.Red, scaledPoint.X - 4, scaledPoint.Y - 4, 7, 7); // 绘制小圆点
}
// 如果有足够的点,绘制连接线
if (points.Count > 1)
{
using (Pen pen = new Pen(Color.Blue, 2)) // 创建一支蓝色画笔
{
for (int i = 0; i < points.Count - 1; i++)
{
Point p1 = new Point((int)(points[i].X * scale), (int)(points[i].Y * scale));
Point p2 = new Point((int)(points[i + 1].X * scale), (int)(points[i + 1].Y * scale));
e.Graphics.DrawLine(pen, p1, p2); // 连接相邻的点
}
}
}
// 连接最后一个点和第一个点形成闭合多边形
if (points.Count > 2)
{
using (Pen pen = new Pen(Color.Blue, 2))
{
Point p1 = new Point((int)(points[points.Count - 1].X * scale), (int)(points[points.Count - 1].Y * scale));
Point p2 = new Point((int)(points[0].X * scale), (int)(points[0].Y * scale));
e.Graphics.DrawLine(pen, p1, p2);
}
}
}
#endregion
public int GetPointIndex(Point location)
{
//循环遍历集合中的坐标,判断是否为空
for (int i = 0; i < points.Count; i++)
{
Point point = points[i];
//Point point = new Point((int)(points[i].X * scale), (int)(points[i].Y * scale));
// 检查点击位置是否在点的范围内
if (Math.Abs(location.X - point.X) <= 10 && Math.Abs(location.Y - point.Y) <= 10)
{
return i;
}
}
return -1;
}
}
}
绘制多边形,可以右键拖动点对多边形放大,可以左键点住点对多边形进行位移
最新推荐文章于 2025-06-12 21:46:27 发布