I have been creating a drawing app as a test for WPF, and have been going well. The problem I\'ve run into is that if I draw the pixel under the mouse to a bitmap each time
I realize that you have already had your question answered, but wanted to post for the sake of anyone else who has this problem. I am one of those people.
I had a situation where my drawings looked exactly like the UPDATE section in the original question. The way I fixed this was by drawing overlapping lines by keeping track of not only the start and end points, but also a midpoint. When I draw, I draw using all three points, and then update start point -> midpoint, midpoint -> end point, end point -> new position relative to whatever you're drawing on. This made my lines look much, much better.
Hopefully this is helpful to someone who had the same issue as me.
If you want to draw a line, you shouldn't just change colors of one pixel at a time, but rather save position of the mouse in each MouseMove
event handling method.
Then, you should draw a line between previous position (the one saved from the previous event occurrence) and draw a Line
between those two points. This will make the line to be continuous. Information about drawing lines on WriteableBitmap
can be found here: Drawing line using WPF WriteableBitmap.BackBuffer.
After drawing the line, don't forget to update the previous position saved to the current one :).
UPDATE
I've also found another solution.
Define XAML with Image you want to draw on:
<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>
And then, add code behind with the events handled:
//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);
}
}