using System;
using System.Collections;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Imaging;
using System.Windows.Forms;
using PhotoSprite.ImageProcessing;namespace PhotoSprite.Tool
{
/// <summary>
/// 矩形工具类
/// </summary>
public class RectangleTool : Tool
{
private Canvas canvas = null;
private Bitmap image = null;
private Bitmap srcImage = null;
private Graphics gImage;
private Graphics gSurface;
private bool mouseDown = false;
private Point startPoint, lastPoint;
private Pen pen = null; /// <summary>
/// 使用矩形工具
/// </summary>
/// <param name="parent">画布</param>
public RectangleTool(Canvas parent)
{
this.canvas = parent;
gSurface = canvas.CreateGraphics();
} public void OnActivate()
{
this.canvas.MouseDown += this.OnMouseDown;
this.canvas.MouseMove += this.OnMouseMove;
this.canvas.MouseUp += this.OnMouseUp;
} public void OnDeactivate()
{
this.canvas.MouseDown -= this.OnMouseDown;
this.canvas.MouseMove -= this.OnMouseMove;
this.canvas.MouseUp -= this.OnMouseUp;
} public void OnMouseDown(object sender, MouseEventArgs e)
{
if (((e.Button & MouseButtons.Left) == MouseButtons.Left) ||
((e.Button & MouseButtons.Right) == MouseButtons.Right))
{
mouseDown = true;
lastPoint = startPoint = new Point(e.X, e.Y); // 左键为前景颜色,右键为背景颜色
if ((e.Button & MouseButtons.Left) == MouseButtons.Left)
{
pen = new Pen(new SolidBrush(this.ForeColor), this.BrushWidth);
}
else if ((e.Button & MouseButtons.Right) == MouseButtons.Right)
{
pen = new Pen(new SolidBrush(this.BackColor), this.BrushWidth);
} // 锁定画布图像
this.image = this.canvas.Image;
this.srcImage = (Bitmap)this.image.Clone();
gImage = System.Drawing.Graphics.FromImage(image);
}
} public void OnMouseMove(object sender, MouseEventArgs e)
{
if (mouseDown)
{
Point mouseXY = new Point(e.X, e.Y);
mouseXY = Function.PointInRectangle(mouseXY, this.canvas.Bounds);
if (mouseXY.X == this.canvas.Width - 1) mouseXY.X = this.canvas.Width - 2;
if (mouseXY.Y == this.canvas.Height - 1) mouseXY.Y = this.canvas.Height - 2;
// 消除上次痕迹
Rectangle lastRect = Function.PointsToRectangle(startPoint, lastPoint);
Rectangle lastOutlineRect = lastRect;
lastOutlineRect.Inflate(2, 2);
Rectangle lastInteriorRect = lastRect;
lastInteriorRect.Inflate(-2, -2);
Region invalidRegion = new Region(lastOutlineRect);
invalidRegion.Xor(lastInteriorRect); this.canvas.Invalidate(invalidRegion);
this.gImage.DrawImage((Bitmap)this.srcImage.Clone(), lastOutlineRect, lastOutlineRect, GraphicsUnit.Pixel);
// 绘制表面
Rectangle rect = Function.PointsToRectangle(startPoint, mouseXY);
//this.gSurface.DrawRectangle(pen, rect); // 绘制到图像
this.gImage.DrawRectangle(pen, rect); lastPoint = mouseXY;
}
} public void OnMouseUp(object sender, MouseEventArgs e)
{
if (mouseDown)
{
Point mouseXY = new Point(e.X, e.Y); // 绘制矩形
Graphics g = Graphics.FromImage(this.srcImage);
g.DrawRectangle(pen, Function.PointsToRectangle(startPoint, mouseXY));
this.gImage.DrawImage((Bitmap)this.srcImage.Clone(), 0,0); startPoint = Point.Empty;
lastPoint = Point.Empty;
mouseDown = false; pen.Dispose();
this.canvas.Invalidate(); // 触发绘图结束事件
OnDrawingFinished();
}
}
/// <summary>
/// 在绘图结束时发生
/// </summary>
public event EventHandler DrawingFinished;
protected void OnDrawingFinished()
{
if (DrawingFinished != null)
{
DrawingFinished(this, EventArgs.Empty);
}
}
}
}
解决方案 »
- 各位大虾,一个list[]数组。我想取出其中list[2]的最后一个元素。该怎么写?代码如下
- 一个小问题
- 库中没有赋值的字段怎么处理?谢谢
- 操作数据库时,为何读了几条记录后,就像休眠似的,然后出现超时错误,然后再继续,要命的是怎么也捕获不到错误出在哪里?
- 竟然出错了!再求一次。100分求助--如何得到axWebbrowser中用户所选择的文字?
- 很奇怪的问题,我做了一个.NET程序(C#),生成安装程序后在别的机器上安装出错
- 我想把当前ListView 中的数据打印出来怎么实现?请高手相助,谢谢!
- C#操作sybase Adaptive Server Anywhere!高手帮忙
- 求DirectX SDK中文版 下载地址
- post登录CSDN的问题
- 从某个字符串中删除指定位置的字符,如何实现
- 如何在treeview的节点前面添加图标?高分求最佳方案
大致就是随着鼠标位置改变而画,有很多自定义的东西,自己慢慢分析吧
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Windows.Forms;
using PhotoSprite.ImageProcessing;namespace PhotoSprite
{
public partial class Canvas : UserControl
{
private Bitmap image = null;
private string imageFile = "";
private double zoom = 1.0; private GraphicsPath selectedPath = new GraphicsPath();
private int dancingAnts = 0;
private static Pen outlinePen = null;
private static Pen antPen = null;
/// <summary>
/// 获取或设置图像
/// </summary>
public Bitmap Image
{
get
{
return image;
}
set
{
image = value;
this.Invalidate();
}
} /// <summary>
/// 获取或设置图像文件
/// </summary>
public string ImageFile
{
get
{
return imageFile;
}
set
{
imageFile = value; if (imageFile != "")
{
Graphic myGraphic = new Graphic();
this.Image = myGraphic.Open(imageFile);
}
}
} /// <summary>
/// 获取或设置画布缩放系数
/// </summary>
public double Zoom
{
get
{
return zoom;
}
set
{
zoom = value;
this.Invalidate();
}
} /// <summary>
/// 获取或设置选区
/// </summary>
public GraphicsPath SelectedPath
{
get
{
return selectedPath;
}
set
{
if (selectedPath != null)
selectedPath.Reset();
selectedPath = value;
}
} /// <summary>
/// 获取 bool 值,以指示是否选区为空
/// </summary>
public bool IsSelectionEmpty
{
get
{
return selectedPath.PointCount == 0;
}
} /// <summary>
/// 获取选区
/// </summary>
public Region SelectedRegion
{
get
{
if (IsSelectionEmpty)
return new Region(new Rectangle(0, 0, this.Size.Width, this.Size.Height));
else
return new Region(selectedPath);
}
} /// <summary>
/// 画布
/// </summary>
public Canvas()
{
InitializeComponent(); this.ResizeRedraw = true;
this.SetStyle( ControlStyles.UserPaint |
ControlStyles.AllPaintingInWmPaint |
ControlStyles.OptimizedDoubleBuffer, true); this.SetStyle(ControlStyles.UserMouse, true); //控制鼠标完成事件
} protected override void OnLoad(EventArgs e)
{
base.OnLoad(e); // 绘制背景,将黑白方块交叉出现的花纹样式视作透明背景
Color black = Color.FromArgb(0xFF, 0xDF, 0xDF, 0xDF);
Color white = Color.White; Bitmap buffer = new Bitmap(16, 16);
Graphics g = System.Drawing.Graphics.FromImage(buffer);
g.FillRectangle(new SolidBrush(black), 0, 0, 8, 8);
g.FillRectangle(new SolidBrush(white), 8, 0, 8, 8);
g.FillRectangle(new SolidBrush(white), 0, 8, 8, 8);
g.FillRectangle(new SolidBrush(black), 8, 8, 8, 8); this.BackgroundImage = buffer;
} protected override void OnResize(EventArgs e)
{
base.OnResize(e);
} protected override void OnPaint(PaintEventArgs e)
{
//base.OnPaint(e); // 绘制图像
if (image != null)
{
this.Size = new Size((int)(this.image.Width * zoom), (int)(this.image.Height * zoom)); e.Graphics.InterpolationMode = InterpolationMode.NearestNeighbor;
e.Graphics.DrawImage(image,
new Rectangle(0, 0, this.Width, this.Height),
new Rectangle(0, 0, image.Width, image.Height),
GraphicsUnit.Pixel
);
}
if (!IsSelectionEmpty)
{
DrawSelectionOutline(e.Graphics, selectedPath);
}
} protected override void OnMouseDown(MouseEventArgs e)
{
base.OnMouseDown(e);
} protected override void OnMouseMove(MouseEventArgs e)
{
base.OnMouseMove(e);
} protected override void OnMouseUp(MouseEventArgs e)
{
base.OnMouseUp(e);
} private void DrawSelectionOutline(Graphics g, GraphicsPath outline)
{
if (outline == null)
{
return;
} g.SmoothingMode = SmoothingMode.AntiAlias; // 绘制轮廓线
if (outlinePen == null)
{
outlinePen = new Pen(Color.FromArgb(200, Color.Black), 1.0f);
outlinePen.Alignment = PenAlignment.Outset;
outlinePen.LineJoin = LineJoin.Round;
} // 绘制蚂蚁线
if (antPen == null)
{
antPen = new Pen(Color.White, 1.0f);
antPen.Alignment = PenAlignment.Outset;
antPen.LineJoin = LineJoin.Round;
antPen.MiterLimit = 2;
antPen.Width = 1.0f;
antPen.DashStyle = DashStyle.Dash;
antPen.DashPattern = new float[] { 4, 4 };
antPen.DashOffset = 4.0f;
}
g.PixelOffsetMode = PixelOffsetMode.Default;
g.DrawPath(outlinePen, outline);
antPen.DashOffset = dancingAnts;
g.DrawPath(antPen, outline); // 填充一个蓝色区域
g.FillPath(new SolidBrush(Color.FromArgb(60, Color.Cyan)), outline);
} private void selectionTimer_Tick(object sender, EventArgs e)
{
if (!IsSelectionEmpty)
{
dancingAnts = unchecked(dancingAnts + 1);
this.Invalidate();
}
} }
}
是啊,《图像编程精髓》的一段代码。CSDN上有源代码下载!!
public void OnMouseMove(object sender, MouseEventArgs e)
{
//判断OnMouseDown是否正确执行,即鼠标是否按键正确
//鼠标移到的过程中必须鼠标左键或右键按住移到,如果移到的过程鼠标释放了
//将触发OnMouseUp事件,mouseDown将赋值为false
//接下去不管鼠标怎么移到,都不会在执行这个if里面的代码
//这个过程表示一个绘制矩形的过程:鼠标单击画布某点 - 鼠标按住不放拖动 - 鼠标释放 - 矩形绘制成功
if (mouseDown)
{
//获取鼠标移到到的某个点的位置
Point mouseXY = new Point(e.X, e.Y); //将鼠标移到的点和画布边缘进行比较,如果移动到画布外面,就修改mouseXY的x和y
//这个主要是防止矩形绘制到画布外面
mouseXY = Function.PointInRectangle(mouseXY, this.canvas.Bounds);
if (mouseXY.X == this.canvas.Width - 1) mouseXY.X = this.canvas.Width - 2;
if (mouseXY.Y == this.canvas.Height - 1) mouseXY.Y = this.canvas.Height - 2; //计算矩形的位置,并进行清除,如果鼠标移动的时候不即时,那么拖动鼠标,将生成很多相同左上角、不同右下角的矩形,他们会叠加在一起
Rectangle lastRect = Function.PointsToRectangle(startPoint, lastPoint);
Rectangle lastOutlineRect = lastRect;
//x和y放大2单位,估计是因为矩形边距的宽度
lastOutlineRect.Inflate(2, 2); Rectangle lastInteriorRect = lastRect;
//恢复初始
lastInteriorRect.Inflate(-2, -2); Region invalidRegion = new Region(lastOutlineRect);
invalidRegion.Xor(lastInteriorRect); this.canvas.Invalidate(invalidRegion);
//在获得画布的Image上面,根据上一步矩形的lastOutlineRect和lastInteriorRect,来重新绘制图片
this.gImage.DrawImage((Bitmap)this.srcImage.Clone(), lastOutlineRect, lastOutlineRect, GraphicsUnit.Pixel); // 根据startPoint和mouseXY这两个点的位置,构造一个矩形表达式
Rectangle rect = Function.PointsToRectangle(startPoint, mouseXY);
this.gSurface.DrawRectangle(pen, rect); //根据rect这个矩形结构表达式,绘制一个矩形
this.gImage.DrawRectangle(pen, rect); //随着鼠标的移到,不断的更新lastPoint的值,在矩形左上角的点不变的基础上,不断变化矩形右下角的点
lastPoint = mouseXY;
}
}
Region invalidRegion = new Region(lastOutlineRect);
invalidRegion.Xor(lastInteriorRect);