实现原理基本截图的功能主要靠响应主窗体的鼠标按下、鼠标移动、鼠标抬起几个事件的功能来实现的。截取的图片区域使用“label”组件来显示,需要重新实现“label”组件的“paint”方法。
左键单击开始截图,右键单击取消截图,双击鼠标左键完成截图,将截取的图片保存到windows剪贴板中。
添加“label”组件工具箱》公共组件》双击“label”组件,修改组件属性:
name=lbl_cutimage,
autosize=false,
backcolor=transparent,
text = “”
“form1_load”事件添加代码:
this.lbl_cutimage.hide();
定义截图功能依赖的基本变量 #region 截图基本变量
/// <summary>
/// 用于判断是否已经开始截图,控制信息框是否显示。
/// </summary>
private bool iscuting;
/// <summary>
/// 鼠标按下的点
/// </summary>
private point beginpoint;
/// <summary>
/// 最终确定的绘图基点
/// </summary>
private point endpoint;
/// <summary>
/// 用于记录截图显示区域的大小(包括调整块的区域,调整区域边框宽度2px)
/// </summary>
private rectangle cutimagerect = new rectangle(0, 0, 5, 5);
#endregion
定义枚举类型:更新ui的模式 /// <summary>
/// 更新ui的模式,用于标记哪些需要显示,哪些需要隐藏;
/// </summary>
[flagsattribute]
public enum updateuimode : uint
{
//值得注意的是,如果要使用组合值,那么就不能用连接的数字表示,必须是几何级增长!
none = 0,
showtextpro = 1,
showpenstyle = 2,
showtoolbox = 4,
showinfobox = 8,
showzoombox = 16,
showcutimage = 32,
hidetextpro = 64,
hidepenstyle = 128,
hidetoolbox = 256,
hideinfobox = 512
}
添加方法:计算并保存截图的区域框的大小 /// <summary>
/// 计算并保存截图的区域框的大小
/// </summary>
private void savecutimagesize(point beginpoint, point endpoint)
{
// 保存最终的绘图基点,用于截取选中的区域
this.endpoint = beginpoint;
// 计算截取图片的大小
int imgwidth = math.abs(endpoint.x - beginpoint.x) + 1;
int imgheight = math.abs(endpoint.y - beginpoint.y) + 1;
int lblwidth = imgwidth + 4;
int lblheight = imgheight + 4;
// 设置截图区域的位置和大小
this.cutimagerect = new rectangle(beginpoint.x - 2, beginpoint.y - 2, lblwidth, lblheight);
}
添加方法:执行截图,将选定区域的图片保存到剪贴板 /// <summary>
/// 执行截图,将选定区域的图片保存到剪贴板
/// </summary>
/// <param name="savetodisk">
/// 是否将图片保存到磁盘
/// </param>
private void execcutimage(bool savetodisk, bool uploadimage) //bool savetodisk = false, bool uploadimage = false
{
// 如果图片获取区域不可见,则退出保存图片过程
if (!this.lbl_cutimage.visible) { return; }
rectangle srcrect = new rectangle();
srcrect.x = this.lbl_cutimage.location.x + 2;
srcrect.y = this.lbl_cutimage.location.y + 2;
srcrect.width = this.lbl_cutimage.width - 4;
srcrect.height = this.lbl_cutimage.height - 4;
rectangle destrect = new rectangle(0, 0, srcrect.width, srcrect.height);
bitmap bmp = new bitmap(srcrect.width, srcrect.height);
graphics g = graphics.fromimage(bmp);
g.drawimage(this.screenimage, destrect, srcrect, graphicsunit.pixel);
clipboard.setimage(bmp);
exitcutimage(true);
}
添加方法:退出截图过程 /// <summary>
/// 退出截图过程
/// </summary>
private void exitcutimage(bool hidewindow) // = true
{
this.lbl_cutimage.visible = false;
this.iscuting = false;
if (hidewindow)
{
this.screenimage.dispose();
this.hide();
}
}
主窗口鼠标按下事件处理程序 /// <summary>
/// 截图窗口鼠标按下事件处理程序
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void form1_mousedown(object sender, mouseeventargs e)
{
// 左键单击事件
if (e.button == mousebuttons.left && e.clicks == 1)
{
if (!this.lbl_cutimage.visible)
{
this.iscuting = true;
this.beginpoint = e.location;
this.endpoint = e.location;
savecutimagesize(e.location, e.location);
updatecutinfolabel(updateuimode.showcutimage | updateuimode.showinfobox);
}
}
// 左键双击事件
if (e.button == mousebuttons.left && e.clicks == 2)
{
if (this.lbl_cutimage.visible)
{
execcutimage(false, false);
}
}
// 右键单击事件
if (e.button == mousebuttons.right)
{
exitcutimage(!this.lbl_cutimage.visible);
}
}
主窗口鼠标移动事件处理程序 /// <summary>
/// 截图窗口鼠标移动事件处理程序
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void form1_mousemove(object sender, mouseeventargs e)
{
// 如果截取区域不可见,则退出处理过程
if (!this.lbl_cutimage.visible)
{
updatecutinfolabel(updateuimode.none);
return;
}
point pntbgn = this.beginpoint;
point pntend = e.location;
// 如果是反向拖动,重新设置起始点
if (e.location.x < this.beginpoint.x && e.location.y < this.beginpoint.y)
{
pntbgn = e.location;
pntend = this.beginpoint;
}
else
{
if (e.location.x < this.beginpoint.x)
{
pntbgn = new point(e.location.x, this.beginpoint.y);
pntend = new point(this.beginpoint.x, e.location.y);
}
else
{
if (e.location.y < this.beginpoint.y)
{
pntbgn = new point(this.beginpoint.x, e.location.y);
pntend = new point(e.location.x, this.beginpoint.y);
}
}
}
if (this.iscuting)
{
savecutimagesize(pntbgn, pntend);
}
updatecutinfolabel(updateuimode.none);
}
主窗口鼠标抬起事件处理程序 /// <summary>
/// 截图窗口鼠标抬起事件处理程序
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void form1_mouseup(object sender, mouseeventargs e)
{
if (e.button == mousebuttons.left)
{
if (this.iscuting)
{
this.iscuting = false;
updatecutinfolabel(updateuimode.none);
}
}
}
截取区域图片绘制 /// <summary>
/// 截取区域图片的绘制事件处理程序
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void lbl_cutimage_paint(object sender, painteventargs e)
{
int imgwidth = this.lbl_cutimage.width - 4;
int imgheight = this.lbl_cutimage.height - 4;
if (imgwidth < 1) { imgwidth = 1; }
if (imgheight < 1) { imgheight = 1; }
// 创建缓存图像,先将要绘制的内容全部绘制到缓存中,最后再一次性绘制到 label 上,
// 这样可以提高性能,并且可以防止屏幕闪烁的问题
bitmap bmp_lbl = new bitmap(this.lbl_cutimage.width, this.lbl_cutimage.height);
graphics g = graphics.fromimage(bmp_lbl);
// 将要截取的部分绘制到缓存
rectangle destrect = new rectangle(2, 2, imgwidth, imgheight);
point srcpoint = this.lbl_cutimage.location;
srcpoint.offset(2, 2);
rectangle srcrect = new rectangle(srcpoint, new system.drawing.size(imgwidth, imgheight));
g.drawimage(this.screenimage, destrect, srcrect, graphicsunit.pixel);
solidbrush brush = new solidbrush(color.fromargb(10, 124, 202));
pen pen = new pen(brush, 1.0f);
//以下部分(边框和调整块)的绘制放在(编辑内容)的后面,是解决绘制编辑内容会覆盖(边框和调整块)的问题
// 绘制边框外的区域,解决会被编辑内容覆盖的问题
// 上边
destrect = new rectangle(0, 0, this.lbl_cutimage.width, 2);
srcpoint = this.lbl_cutimage.location;
//srcpoint.offset(2, 2);
srcrect = new rectangle(srcpoint, new system.drawing.size(this.lbl_cutimage.width, 2));
g.drawimage(this.backgroundimage, destrect, srcrect, graphicsunit.pixel);
// 下边
destrect = new rectangle(0, this.lbl_cutimage.height - 2, this.lbl_cutimage.width, 2);
srcpoint = this.lbl_cutimage.location;
srcpoint.offset(0, this.lbl_cutimage.height - 2);
srcrect = new rectangle(srcpoint, new system.drawing.size(this.lbl_cutimage.width, 2));
g.drawimage(this.backgroundimage, destrect, srcrect, graphicsunit.pixel);
// 左边
destrect = new rectangle(0, 2, 2, this.lbl_cutimage.height - 4);
srcpoint = this.lbl_cutimage.location;
srcpoint.offset(0, 2);
srcrect = new rectangle(srcpoint, new system.drawing.size(2, this.lbl_cutimage.height - 4));
g.drawimage(this.backgroundimage, destrect, srcrect, graphicsunit.pixel);
// 右边
destrect = new rectangle(this.lbl_cutimage.width - 2, 2, 2, this.lbl_cutimage.height - 4);
srcpoint = this.lbl_cutimage.location;
srcpoint.offset(this.lbl_cutimage.width - 2, 2);
srcrect = new rectangle(srcpoint, new system.drawing.size(2, this.lbl_cutimage.height - 4));
g.drawimage(this.backgroundimage, destrect, srcrect, graphicsunit.pixel);
// 绘制边框
g.drawline(pen, 2, 2, this.lbl_cutimage.width - 3, 2);
g.drawline(pen, 2, 2, 2, this.lbl_cutimage.height - 3);
g.drawline(pen, this.lbl_cutimage.width - 3, 2, this.lbl_cutimage.width - 3, this.lbl_cutimage.height - 3);
g.drawline(pen, 2, this.lbl_cutimage.height - 3, this.lbl_cutimage.width - 3, this.lbl_cutimage.height - 3);
// 绘制四个角的调整块
g.fillrectangle(brush, 0, 0, 4, 5);
g.fillrectangle(brush, this.lbl_cutimage.width - 4, 0, 4, 5);
g.fillrectangle(brush, 0, this.lbl_cutimage.height - 5, 4, 5);
g.fillrectangle(brush, this.lbl_cutimage.width - 4, this.lbl_cutimage.height - 5, 4, 5);
// 绘制中间的四个调整块
int blockx = this.lbl_cutimage.width / 2 - 2;
int blocky = this.lbl_cutimage.height / 2 - 2;
g.fillrectangle(brush, blockx, 0, 4, 5);
g.fillrectangle(brush, 0, blocky, 4, 5);
g.fillrectangle(brush, blockx, this.lbl_cutimage.height - 5, 4, 5);
g.fillrectangle(brush, this.lbl_cutimage.width - 4, blocky, 4, 5);
// 绘制到 label 上
e.graphics.drawimage(bmp_lbl, 0, 0);
bmp_lbl.dispose();
}
双击鼠标左键完成截图功能 /// <summary>
/// 截取区域图片的鼠标按下事件处理程序
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void lbl_cutimage_mousedown(object sender, mouseeventargs e)
{
// 左键双击事件
if (e.button == mousebuttons.left && e.clicks == 2)
{
if (this.lbl_cutimage.visible)
{
execcutimage(false, false);
}
}
}
注意:代码都贴完了,别忘了为窗体或组件绑定事件处理程序;
例如:截取区域图片的鼠标按下事件处理程序“lbl_cutimage_mousedown”,就是“lbl_cutimage”组件的“mousedown”事件的处理程序,绑定方法参考下图:
到此,基本截图的功能实现已经实现,赶快去截取一张图片,粘贴到qq的聊天窗口看看吧。
以上就是c#开发实例-订制屏幕截图工具(四)基本截图功能实现代码的详细内容。