C#软件开发实例.私人订制自己的屏幕截图工具——放大镜的功能代码优化

简介: 最近在使用屏幕截图工具的时候发现放大镜的功能有点小问题,准星和实际鼠标位置对不上,取到的颜色并不鼠标所在的点颜色,所以去看“C#软件开发实例.私人订制自己的屏幕截图工具(七)添加放大镜的功能”的代码,发现之前的代码实现效率上应该有问题,所以就试试优化了一下,经过对比相差十几倍。

最近在使用屏幕截图工具的时候发现放大镜的功能有点小问题,准星和实际鼠标位置对不上,取到的颜色并不鼠标所在的点颜色,所以去看“C#软件开发实例.私人订制自己的屏幕截图工具(七)添加放大镜的功能”的代码,发现之前的代码实现效率上应该有问题,所以就试试优化了一下,经过对比相差十几倍。

之前的算法逻辑是:

1、根据放大镜的大小计算需要的原图尺寸,复制到新建的Bitmap;

2、创建一个新的Bitmap保存放大后的图片;

3、采用四层循环通过“GetPixel”获得源像素颜色,通过“SetPixel”设置放大后目标区域颜色;

优化后的逻辑:

1、根据放大镜的大小计算需要的原图尺寸,获取原图在整个屏幕图片上的坐标点;

2、声明单像素放大的区域“zoomRect”,1:10放大,所以Reatangle大小是10*10;

3、声明画笔对象;

4、双层循环,直接从屏幕图片上取像素点的颜色,通过“FillRectangle”方法对像素进行放大绘制到放大镜的对应显示区域;

优化后的代码:

                long drawBegin = DateTime.Now.Ticks;
                //绘制放大镜中的图像
                int infoAreaHeight = 32;
                Size srcSize = new System.Drawing.Size((int)(this.ZoomBoxWidth / 10), (int)(this.ZoomBoxHeight / 10));
                Point srcPoint = new Point(MousePosition.X - 5, MousePosition.Y - 4);
                if (!isCuting)
                {
                    label1.Text = "!isCuting";
                    srcPoint = new Point(MousePosition.X - 6, MousePosition.Y - 5);
                }

                Rectangle zoomRect  = new Rectangle(0, 0, 10, 10);
                Brush zoomBrush;
                for (int row = 0; row < srcSize.Height; row++)
                {
                    for (int col = 0; col < srcSize.Width; col++)
                    {
                        Color pc = screenImage.GetPixel(srcPoint.X + col, srcPoint.Y + row);
                        zoomBrush = new SolidBrush(pc);
                        e.Graphics.FillRectangle(zoomBrush, zoomRect);
                        zoomRect.Offset(10, 0);
                    }
                    zoomRect.Offset(0, 10);
                    zoomRect.X = 0;
                }

                //绘制放大镜的准星
                int blockX = e.ClipRectangle.Width / 2;
                int blockY = (e.ClipRectangle.Height - infoAreaHeight) / 2;

                SolidBrush brush = new SolidBrush(Color.FromArgb(10, 124, 202));
                Pen pen = new Pen(brush, 2.0F);
                e.Graphics.DrawLine(pen, new Point(0, blockY + 5), new Point(e.ClipRectangle.Width, blockY + 5)); //加5解决放大镜准星和实际鼠标位置对不上的问题;
                e.Graphics.DrawLine(pen, new Point(blockX, 0), new Point(blockX, e.ClipRectangle.Height - infoAreaHeight));
                
                //绘制信息区墨色背景
                Rectangle rectInfo = new Rectangle(0, e.ClipRectangle.Height - infoAreaHeight, e.ClipRectangle.Width, infoAreaHeight);
                brush = new SolidBrush(Color.FromArgb(51, 51, 51));
                e.Graphics.FillRectangle(brush, rectInfo);
                
                //计算截图区域的大小
                if (this.lbl_CutImage.Visible)
                {
                    this.areaSize = new System.Drawing.Size(this.lbl_CutImage.Width - 4, this.lbl_CutImage.Height - 4);
                    if (this.areaSize.Width < 1) { this.areaSize.Width = 1; }
                    if (this.areaSize.Height < 1) { this.areaSize.Height = 1; }
                }
                else
                {
                    this.areaSize = rect_WindowFromPoint.Size;
                }

                //绘制截取区域大小
                brush = new SolidBrush(Color.White);
                Font font = new System.Drawing.Font(FontFamily.GenericSerif, 12.0F, GraphicsUnit.Pixel);
                string str = this.areaSize.Width + " x " + this.areaSize.Height;
                e.Graphics.DrawString(str, font, brush, new PointF(5, rectInfo.Top + 1));

                //绘制鼠标指针位置的颜色
                this.cRGB = screenImage.GetPixel(MousePosition.X, MousePosition.Y);
                str = "RGB:#" + this.cRGB.R.ToString("X").PadLeft(2, '0') + this.cRGB.G.ToString("X").PadLeft(2, '0') + this.cRGB.B.ToString("X").PadLeft(2, '0');
                e.Graphics.DrawString(str, font, brush, new PointF(5, rectInfo.Top + 15));

                label1.Text = "," + (DateTime.Now.Ticks - drawBegin);
                Application.DoEvents();

效率检测方法:

//在要测试的代码前添加变量记录时间
long drawBegin = DateTime.Now.Ticks;
//中间为要测试的代码
//在要测试的代码后添加代码显示时间差
label1.Text = "," + (DateTime.Now.Ticks - drawBegin);
Application.DoEvents();

小结

这里有这样几个优化点:

1、省去两个Bitmap对象,就省去两次绘制开销;

2、四层循环改为两层循环,计算量减小;

3、使用“FillRectangle”方法代替“SetPixel”;

本项目完整源码请参考:【拥抱开源】十年之做C#屏幕截图工具全面开源

======================文档信息===========================

版权声明:非商用自由转载-保持署名-注明出处

署名(BY) :testcs_dn(微wx笑)

文章出处:[无知人生,记录点滴](http://blog.csdn.net/testcs_dn)

目录
相关文章
|
19天前
|
C#
【C#】 如何实现文本框历史记录提示功能
【C#】 如何实现文本框历史记录提示功能
20 0
|
3月前
|
自然语言处理 C# Windows
C#开源免费的Windows右键菜单管理工具
C#开源免费的Windows右键菜单管理工具
|
11天前
|
编译器 C# 开发工具
C# 12 中新增的几大功能你都知道吗?
C# 12 中新增的几大功能你都知道吗?
|
11天前
|
IDE C# 开发工具
一个开源轻量级的C#代码格式化工具(支持VS和VS Code)
一个开源轻量级的C#代码格式化工具(支持VS和VS Code)
|
8天前
|
C# Windows
C#开源的两款功能强大的录屏神器
C#开源的两款功能强大的录屏神器
|
2月前
|
数据挖掘 C# 开发工具
采用C#语言开发的全套医院体检系统PEIS源码功能介绍
体检系统,是专为体检中心/医院体检科等体检机构,专门开发的全流程管理系统,通过软件实现检测仪器数据自动提取,内置多级医生工作台,细化工作将体检检查结果汇总,生成体检报告登记到计算机系统中。通过软件系统进行数据分析统计与评判以及建立体检相关的体检档案。从而实现体检流程的信息化,提高工作效率,减少手动结果录入的一些常犯错误。 在实际应用中,医院体检系统能够解决传统体检中手工操作带来的问题,如工作量大、效率低下、易漏检、重检或错检等。通过与医院信息系统(如HIS、LIS、PACS等)的连接,系统能够满足体检中心的日常工作流程,提供更好的管理、统计和查询分析功能。同时,基于网络基础的系统可以在网上传输
29 1
|
3月前
|
编译器 C# 开发工具
C# 12 中新增的八大功能你都知道吗?
C# 12 中新增的八大功能你都知道吗?
|
21天前
|
开发框架 前端开发 .NET
C#编程与Web开发
【4月更文挑战第21天】本文探讨了C#在Web开发中的应用,包括使用ASP.NET框架、MVC模式、Web API和Entity Framework。C#作为.NET框架的主要语言,结合这些工具,能创建动态、高效的Web应用。实际案例涉及企业级应用、电子商务和社交媒体平台。尽管面临竞争和挑战,但C#在Web开发领域的前景将持续拓展。
|
21天前
|
SQL 开发框架 安全
C#编程与多线程处理
【4月更文挑战第21天】探索C#多线程处理,提升程序性能与响应性。了解C#中的Thread、Task类及Async/Await关键字,掌握线程同步与安全,实践并发计算、网络服务及UI优化。跟随未来发展趋势,利用C#打造高效应用。