You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C#快速绘图时线条出现间隙问题求助(附代码)

解决图片画笔快速绘图出现间隙的问题

问题根源

你当前的代码仅在每次MouseMove触发时绘制单张图片,但鼠标快速移动时,系统触发MouseMove的间隔会变大,相邻两次绘制的位置距离超过图片尺寸,就会出现间隙。另外用CreateGraphics绘制的内容不会持久化,窗口重绘后绘制的内容会消失,这也是需要修复的问题。

解决方案

核心思路是记录上一次鼠标位置,在两次鼠标位置之间的路径上连续绘制图片,同时把绘制内容缓存到Bitmap中,通过Panel的Paint事件渲染,保证内容持久不丢失。

修改后的完整代码:

using System;
using System.Drawing;
using System.Windows.Forms;

namespace drawing_using_image
{
    public partial class Form1 : Form
    {
        private Image _brushImage;
        private Bitmap _canvasBitmap;
        private Point _lastMousePos = Point.Empty;
        private int _brushSize = 45; // 和你设置的图片尺寸保持一致

        public Form1()
        {
            InitializeComponent();
            _brushImage = Properties.Resources.angle45;
            // 初始化画布Bitmap,尺寸和Panel一致
            _canvasBitmap = new Bitmap(panel1.Width, panel1.Height);
            // 绑定Panel的Paint事件,用于渲染缓存画布
            panel1.Paint += Panel1_Paint;
            // 监听Panel尺寸变化,重新初始化画布
            panel1.Resize += (s, e) => 
            {
                _canvasBitmap?.Dispose();
                _canvasBitmap = new Bitmap(panel1.Width, panel1.Height);
                panel1.Invalidate();
            };
        }

        private void Panel1_Paint(object sender, PaintEventArgs e)
        {
            // 将缓存的画布内容绘制到Panel上
            e.Graphics.DrawImage(_canvasBitmap, Point.Empty);
        }

        private void panel1_MouseDown(object sender, MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Left)
            {
                // 鼠标按下时记录初始位置
                _lastMousePos = e.Location;
                // 在初始位置绘制一次画笔
                DrawBrushAtPosition(e.Location);
            }
        }

        private void panel1_MouseMove(object sender, MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Left && _lastMousePos != Point.Empty)
            {
                Point currentPos = e.Location;
                // 计算两次鼠标位置的直线距离
                double distance = Math.Sqrt(Math.Pow(currentPos.X - _lastMousePos.X, 2) + Math.Pow(currentPos.Y - _lastMousePos.Y, 2));
                
                if (distance > 0)
                {
                    // 计算每步的移动增量(取画笔尺寸的一半作为步长,确保无间隙)
                    float stepX = (currentPos.X - _lastMousePos.X) / (float)distance * (_brushSize / 2f);
                    float stepY = (currentPos.Y - _lastMousePos.Y) / (float)distance * (_brushSize / 2f);

                    float currentX = _lastMousePos.X;
                    float currentY = _lastMousePos.Y;

                    // 沿着路径循环绘制,直到接近当前鼠标位置
                    while (Math.Sqrt(Math.Pow(currentX - currentPos.X, 2) + Math.Pow(currentY - currentPos.Y, 2)) > _brushSize / 2f)
                    {
                        DrawBrushAtPosition(new Point((int)currentX, (int)currentY));
                        currentX += stepX;
                        currentY += stepY;
                    }
                }

                // 在当前鼠标位置补画一次
                DrawBrushAtPosition(currentPos);
                // 更新上一次鼠标位置
                _lastMousePos = currentPos;
            }
        }

        private void panel1_MouseUp(object sender, MouseEventArgs e)
        {
            // 鼠标松开时重置上一次位置,避免误绘制
            _lastMousePos = Point.Empty;
        }

        private void DrawBrushAtPosition(Point pos)
        {
            // 在缓存画布上绘制图片,以鼠标点为中心
            using (Graphics g = Graphics.FromImage(_canvasBitmap))
            {
                Rectangle rect = new Rectangle(pos.X - _brushSize/2, pos.Y - _brushSize/2, _brushSize, _brushSize);
                g.DrawImage(_brushImage, rect);
            }
            // 通知Panel重绘,更新显示内容
            panel1.Invalidate();
        }
    }
}

关键修改说明

  • 新增_canvasBitmap作为绘制缓存,所有绘制操作都在这个Bitmap上进行,解决了CreateGraphics临时绘制的内容丢失问题
  • 记录_lastMousePos,在MouseMove时计算两次位置的路径,按步长连续绘制图片,彻底填补间隙
  • 将图片绘制位置调整为以鼠标点为中心,更符合画笔的使用直觉
  • 处理Panel的Resize事件,保证画布尺寸始终和Panel一致
  • 新增MouseUp事件,重置上一次位置,避免松开鼠标后出现误绘制

内容的提问来源于stack exchange,提问作者Hassn shalabi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.20 20:52:34