【问题标题】:Drawing with mouse causes gaps between pixels用鼠标绘图会导致像素之间出现间隙
【发布时间】:2012-02-10 18:48:35
【问题描述】:

我一直在创建一个绘图应用程序作为 WPF 的测试,并且进展顺利。我遇到的问题是,如果我每次移动鼠标下的像素到位图上,每次更新我只会得到一个像素。当鼠标快速移动时,它不会在两者之间绘制像素。我需要知道在 WPF 中使用WriteableBitmap在像素之间画线的最佳方法是什么

编辑:现在我有了这个:

【问题讨论】:

标签: c# wpf graphics bitmap drawing


【解决方案1】:

如果你想画一条线,你不应该一次只改变一个像素的颜色,而是在每个MouseMove事件处理方法中保存鼠标的位置。

然后,您应该在之前的位置(从之前的事件发生中保存的位置)之间画一条线,并在这两点之间画一条Line。这将使线是连续的。有关在WriteableBitmap 上绘制线条的信息可以在这里找到:Drawing line using WPF WriteableBitmap.BackBuffer

画完线后,别忘了把之前保存的位置更新到当前位置:)。

更新

我还找到了另一个解决方案。

使用要绘制的图像定义 XAML:

<Window x:Class="SampleWPFApplication.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="MainWindow" Height="500" Width="520" Loaded="Window_Loaded" PreviewMouseDown="Window_PreviewMouseDown">
<Grid x:Name="layoutRoot" Background="Transparent">
    <Image x:Name="image" />
</Grid>

然后,添加处理事件的代码:

//set width and height of your choice
RenderTargetBitmap bmp = null;
//...
private void Window_Loaded(object sender, RoutedEventArgs e)
    {
        //initialize RenderTargetBitmap object
        bmp = new RenderTargetBitmap((int)this.ActualWidth, (int)this.ActualHeight, 90, 90, PixelFormats.Default);

        //set initialized bmp as image's source
        image.Source = bmp;
    }

    /// <summary>
    /// Helper method drawing a line.
    /// </summary>
    /// <param name="p1">Start point of the line to draw.</param>
    /// <param name="p2">End point of the line to draw.</param>
    /// <param name="pen">Pen to use to draw the line.</param>
    /// <param name="thickness">Thickness of the line to draw.</param>
    private void DrawLine(Point p1, Point p2, Pen pen, double thickness)
    {
        DrawingVisual drawingVisual = new DrawingVisual();

        using (DrawingContext drawingContext = drawingVisual.RenderOpen())
        {
            //set properties of the Pen object to make the line more smooth
            pen.Thickness = thickness;
            pen.StartLineCap = PenLineCap.Round;
            pen.EndLineCap = PenLineCap.Round;

            //write your drawing code here
            drawingContext.DrawLine(pen, p1, p2);
        }
    }

【讨论】:

  • Bitmap 类在什么命名空间中?我必须使用 gdi+ 中的类吗?
  • 好的,现在它工作得更好了,但线路没有连接。查看我更新的问题
【解决方案2】:

我知道您已经回答了您的问题,但为了其他遇到此问题的人而想发帖。我是那些人的其中一个。

我的绘图看起来与原始问题中的 UPDATE 部分完全相同。我解决这个问题的方法是通过跟踪起点和终点以及中点来绘制重叠线。绘制时,我使用所有三个点进行绘制,然后更新起点-> 中点、中点-> 终点、终点-> 相对于您正在绘制的任何位置的新位置。这让我的线条看起来好多了,好多了。

希望这对和我有同样问题的人有所帮助。

【讨论】: