画矩形
画四边形
保存标注图片
保存标注信息
代码
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Drawing.Imaging;
using System.Drawing.Drawing2D;
using System.IO;
namespace lxw_Lable
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private SolidBrush fill_brush = new SolidBrush(Color.FromArgb(100, Color.White));
private Pen line_color = new Pen(new SolidBrush(Color.Red), 2);
private Pen pen_yellow = new Pen(new SolidBrush(Color.Yellow), 2);
private Pen pen_red = new Pen(new SolidBrush(Color.Red), 2);
private Graphics draw_paint, merge_paint;//中间画板
private Image tmp_bitmap;//用来保存绘图痕迹
List<Point> polyPoints = null;//存储绘制多边形的点集
List<List<Point>> ltPoly = new List<List<Point>>();//图形信息,最终保存和导出
Rectangle rectA;//存储要用于绘图的矩形
Image bg_image;//背景图片
Point start; //起始点
Point end; //结束点
bool need_draw_tmp; //在MouseMove事件中判断是否绘制矩形框
string action_type = "";//绘图动作类型
bool is_first_down = true;//判断是否第一次按下鼠标
private void button1_Click(object sender, EventArgs e)
{
OpenFileDialog ofd = new OpenFileDialog();
ofd.Title = "请选择图片";
ofd.Filter = "jpg图片|*.JPG|jpeg图片|*.JPEG|gif图片|*.GIF|png图片|*.PNG";//文件类型
ofd.Multiselect = false;
if (ofd.ShowDialog() == DialogResult.OK)
{
string image_path = ofd.FileName;
//中间画布
tmp_bitmap = new Bitmap(image_path);
//创建空白画板
draw_paint = Graphics.FromImage(tmp_bitmap);
bg_image = Image.FromFile(image_path);
pictureBox1.Image = bg_image;
}
}
private void button2_Click(object sender, EventArgs e)
{
if (pictureBox1.Image == null)
{
return;
}
SaveFileDialog sfd = new SaveFileDialog();
sfd.Filter = "jpeg图片|*.JPEG|gif图片|*.GIF|png图片|*.PNG";//设置文件类型
sfd.FileName = "temp";//设置默认文件名
sfd.AddExtension = true;//设置自动在文件名中添加扩展名
if (sfd.ShowDialog() == DialogResult.OK)
{
Bitmap bmp = new Bitmap(pictureBox1.Image);
ImageFormat imageformat = null;
switch (sfd.FilterIndex)
{
case 1:
imageformat = System.Drawing.Imaging.ImageFormat.Jpeg;
break;
case 2:
imageformat = System.Drawing.Imaging.ImageFormat.Gif;
break;
case 3:
imageformat = System.Drawing.Imaging.ImageFormat.Png;
break;
}
Graphics g = Graphics.FromImage(bmp);
//画图
foreach (var item in ltPoly)
{
draw_paint.DrawPolygon(line_color, item.ToArray());
}
bmp.Save(sfd.FileName, imageformat);
bmp.Dispose();
g.Dispose();
MessageBox.Show("保存成功!", "注意", MessageBoxButtons.OK, MessageBoxIcon.Information);
//打开文件
System.Diagnostics.Process.Start(sfd.FileName.ToString());
//打开文件夹
//System.Diagnostics.Process.Start(localFilePath.Substring(0, localFilePath.LastIndexOf("\\")));
}
}
private void Form1_Load(object sender, EventArgs e)
{
comboBox1.SelectedIndex = 0;
action_type = "矩形";
}
private void pictureBox1_MouseDown(object sender, MouseEventArgs e)
{
if (pictureBox1.Image == null)
{
MessageBox.Show("请先选择图片");
return;
}
if (action_type.IndexOf("矩形") >= 0)
{
if (e.Button == MouseButtons.Left)
{
start = e.Location;
need_draw_tmp = true;
}
}
else if (action_type.IndexOf("四边形") >= 0)
{
Graphics g = pictureBox1.CreateGraphics();
//绘制多边形 low版本
if (is_first_down) //首先第一次创建两个点如下(e.X, e.Y),( e.X + 1, e.Y + 1)
{
//first point down
if (e.Button == MouseButtons.Left)
{
is_first_down = false;
if (polyPoints == null) polyPoints = new List<Point>();
polyPoints.Add(e.Location);
need_draw_tmp = true;
}
}
else
{
//add new point
if (e.Button == MouseButtons.Left)
{
//添加新的点
Point point = new Point(e.X, e.Y);
polyPoints.Add(point);
if (polyPoints.Count > 0 && polyPoints.Count % 4 == 0)
{
//转化坐标
Point temp;
List<Point> ltTempPoints = new List<Point>();
foreach (var item in polyPoints)
{
GetImagePixLocation(pictureBox1, item, out temp);
ltTempPoints.Add(temp);
}
polyPoints = ltTempPoints;
ltPoly.Add(polyPoints);
DrawPloy(true);
}
}
}
}
end = e.Location;
pictureBox1.Invalidate();
}
private void pictureBox1_MouseMove(object sender, MouseEventArgs e)
{
if (action_type.IndexOf("矩形") >= 0)
{
//绘制矩形框 并填充
if (need_draw_tmp)
{
if (e.Button != MouseButtons.Left) return;
end = e.Location;
pictureBox1.Invalidate();
}
}
else if (action_type.IndexOf("四边形") >= 0)
{
//绘制多边形
if (need_draw_tmp)
{
//if (e.Button != MouseButtons.Left) return;
end = e.Location;
pictureBox1.Invalidate();//此代码不可省略
//Graphics g = pictureBox1.CreateGraphics();
//抗锯齿
}
}
}
private void pictureBox1_MouseUp(object sender, MouseEventArgs e)
{
if (action_type.IndexOf("矩形") >= 0)
{
//绘制矩形框
if (e.Button == MouseButtons.Left)
{
end = e.Location;
need_draw_tmp = false;
}
Graphics g = pictureBox1.CreateGraphics();
Point temp_start;
Point temp_end;
GetImagePixLocation(pictureBox1, start, out temp_start);
GetImagePixLocation(pictureBox1, end, out temp_end);
Rectangle temp_rect = new Rectangle(Math.Min(temp_start.X, temp_end.X),
Math.Min(temp_start.Y, temp_end.Y),
Math.Abs(temp_start.X - temp_end.X),
Math.Abs(temp_start.Y - temp_end.Y));
draw_paint.DrawRectangle(line_color, temp_rect);//画矩形
//TODO: 扩充点 可弹出选择框选择标注类型
Point[] tempPoints = new Point[4];
tempPoints[0] = new Point(Math.Min(temp_start.X, temp_end.X), Math.Min(temp_start.Y, temp_end.Y));
tempPoints[2] = new Point(Math.Max(temp_start.X, temp_end.X), Math.Max(temp_start.Y, temp_end.Y));
tempPoints[1] = new Point(tempPoints[2].X, tempPoints[0].Y);
tempPoints[3] = new Point(tempPoints[0].X, tempPoints[2].Y);
ltPoly.Add(tempPoints.ToList());
pictureBox1.Image = GetMergeBitmap();
g.Dispose();
}
}
private void pictureBox1_Paint(object sender, PaintEventArgs e)
{
PictureBox pic = sender as PictureBox;
if (action_type.IndexOf("矩形") >= 0)
{
//绘制矩形框 并填充
Pen pen = new Pen(Color.Red, 3);
pen.DashStyle = System.Drawing.Drawing2D.DashStyle.Dot; //绘制线的格式
//绘制矩形框 并填充
if (need_draw_tmp)
{
//此处是为了在绘制时可以由上向下绘制,也可以由下向上
rectA = new Rectangle(Math.Min(start.X, end.X), Math.Min(start.Y, end.Y), Math.Abs(start.X - end.X), Math.Abs(start.Y - end.Y));
e.Graphics.DrawRectangle(pen, rectA);
}
pen.Dispose();
}
else if (action_type.IndexOf("四边形") >= 0)
{
//多边形
if (polyPoints != null)
{
if (need_draw_tmp)
{
//抗锯齿
e.Graphics.SmoothingMode = SmoothingMode.AntiAlias;
e.Graphics.DrawLine(pen_yellow, polyPoints.First(), end);
e.Graphics.DrawLine(pen_red, polyPoints.Last(), end);
if (polyPoints.Count > 1)
{
for (int i = 0; i < polyPoints.Count - 1; i++)
{
e.Graphics.DrawLine(pen_red, polyPoints[i], polyPoints[i + 1]);
}
}
}
}
}
}
private Bitmap GetMergeBitmap()
{
Bitmap tmp_bmp = (Bitmap)bg_image.Clone();
merge_paint = Graphics.FromImage(tmp_bmp);
merge_paint.DrawImage(tmp_bitmap, 0, 0);//将中间画布绘制的内容绘制到原始画布上
merge_paint.Dispose();
return tmp_bmp;
}
private void GetImagePixLocation(PictureBox pictureBox, System.Drawing.Point pictureBoxPoint, out System.Drawing.Point imagePoint)
{
imagePoint = new System.Drawing.Point(0, 0);
System.Drawing.Size imageSize = pictureBox.Image.Size;
double scale;
int detalInHeight = 0;
int detalInWidth = 0;
if (Convert.ToDouble(pictureBox.Size.Width) / pictureBox.Size.Height > Convert.ToDouble(imageSize.Width) / imageSize.Height)
{
scale = 1.0 * imageSize.Height / pictureBox.Size.Height;
detalInWidth = Convert.ToInt32((pictureBox.Size.Width * scale - imageSize.Width) / 2.0);
}
else
{
scale = 1.0 * imageSize.Width / pictureBox.Size.Width;
detalInHeight = Convert.ToInt32((pictureBox.Size.Height * scale - imageSize.Height) / 2.0);
}
imagePoint.X = Convert.ToInt32(pictureBoxPoint.X * scale - detalInWidth);
imagePoint.Y = Convert.ToInt32(pictureBoxPoint.Y * scale - detalInHeight);
}
private void DrawPloy(bool fill = true)
{
//绘制矩形框 并填充
draw_paint.SmoothingMode = SmoothingMode.HighQuality;//抗锯齿
draw_paint.DrawPolygon(line_color, polyPoints.ToArray());
//填充多边形
if (fill)
{
draw_paint.FillPolygon(fill_brush, polyPoints.ToArray());
}
//TODO: 扩充点 可弹出选择框选择标注类型
pictureBox1.Image = GetMergeBitmap();
is_first_down = true;
need_draw_tmp = false;
polyPoints = null;
}
private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
{
action_type = comboBox1.Text;
}
private void button3_Click(object sender, EventArgs e)
{
if (ltPoly.Count == 0)
{
return;
}
string file = "lable.txt";
FileStream fs = new FileStream(file, FileMode.Create);
StreamWriter sw = new StreamWriter(fs, Encoding.UTF8);
foreach (var item in ltPoly)
{
sw.WriteLine(string.Format("({0},{1}),({2},{3}),({4},{5}),({6},{7})",
item[0].X, item[0].Y,
item[1].X, item[1].Y,
item[2].X, item[2].Y,
item[3].X, item[3].Y
));
}
sw.Close();
fs.Close();
MessageBox.Show("保存成功!", "注意", MessageBoxButtons.OK, MessageBoxIcon.Information);
//打开文件
System.Diagnostics.Process.Start(file);
}
}
}
Demo下载