如何在pictureBox1的MouseMove事件中实时绘制红色像素?
问题分析与修复方案
原代码存在的核心问题
- 冗余循环导致性能暴跌:你添加了两层遍历整个图像像素的
for循环,但循环体内始终只修改同一个(e.X, e.Y)位置的像素,这是完全无效的重复操作,会让MouseMove事件执行大量无意义计算,直接拖慢程序。 - 未更新控件显示:修改
Bitmap后,既没有把修改后的图像赋值回pictureBox1.Image,还立刻调用了Dispose()销毁对象,导致界面完全看不到任何绘制效果。 - 频繁创建Bitmap对象:每次鼠标移动都从
pictureBox1.Image新建Bitmap,带来不必要的内存开销和性能损耗。
修复后的代码
public partial class Form1 : Form { private Bitmap _canvasBitmap; public Form1() { InitializeComponent(); // 复制资源图像到全局Bitmap(资源文件为只读,无法直接修改) _canvasBitmap = new Bitmap(Properties.Resources._image); pictureBox1.Image = _canvasBitmap; } private void pictureBox1_MouseMove(object sender, MouseEventArgs e) { label1.Text = $"X: {e.X}; Y: {e.Y}"; // 检查鼠标坐标是否在图像范围内,避免越界异常 if (e.X >= 0 && e.X < _canvasBitmap.Width && e.Y >= 0 && e.Y < _canvasBitmap.Height) { // 直接修改鼠标位置的像素,无需冗余循环 _canvasBitmap.SetPixel(e.X, e.Y, Color.Red); // 触发控件重绘,显示修改后的图像 pictureBox1.Invalidate(); } } // 窗体关闭时释放Bitmap资源,避免内存泄漏 private void Form1_FormClosed(object sender, FormClosedEventArgs e) { _canvasBitmap?.Dispose(); } }
修复说明
- 使用全局
_canvasBitmap存储图像,避免每次鼠标移动都新建对象,同时解决资源文件只读的问题。 - 移除完全多余的嵌套循环,直接修改目标像素,大幅提升性能。
- 增加坐标合法性检查,防止鼠标移出图像区域时触发越界错误。
- 调用
pictureBox1.Invalidate()触发控件重绘,让修改后的图像实时显示在界面上。 - 在窗体关闭时释放Bitmap资源,避免内存泄漏。
内容的提问来源于stack exchange,提问作者Daniel Lip
相关产品推荐
相关产品推荐

