when I draw something like that (just random drawings here):
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
DrawingVisual visual = new DrawingVisual();
DrawingContext context = visual.RenderOpen();
Pen pen = new Pen(Brushes.Black, 1);
context.DrawEllipse(Brushes.YellowGreen, pen, new Point(0,0), 40, 40);
for (int i = 0; i <= 100 - 1; i++)
context.DrawLine(new Pen(Brushes.Black, 1), new Point(0, i), new Point(i, i));
context.Close();
RenderTargetBitmap bmp = new RenderTargetBitmap(100, 100, 96, 96, PixelFormats.Pbgra32);
bmp.Render(visual);
image1.Source = bmp;
}
}
the colors of DrawLine and DrawEllipse mix. (I figured out that it's only with DrawLine which uses a pen, and not with other forms like Rectangle and Ellipse, that use a Brush). Strangely even with colors from the LinearGradientBrush of a underlying Grids' Background (argh). I would like them to be z-Ordered with full opacity each.
Here the XAML code:
<Window x:Class="WpfApplication2.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<Image Name="image1" Stretch="None" />
</Window>
Thanks for any help.
There are two issues of antialiasing, or sub-pixeling, with RenderTargetBitmap:
1.
Disabling sub-pixeling for the bitmap itself (for example, when it is rendered within a UIElement). this is resolved by applying:
RenderOptions.SetBitmapScalingMode(image1, BitmapScalingMode.NearestNeighbor);
(where image1 is the WPF Image object).
It is only supported for .NET 4 and above. In your specific case it doesn't matter as the lines are rendered pixel-after-pixel.
2.
Disabling sub-pixeling when rendering INTO the RenderTargetBitmap. It can be achieved by the method RenderOptions.SetEdgeMode with the parameter value of EdgeMode.Aliased.
HOWEVER, this method will work only if:
The method is called for a DrawingGroup object.
The antialiased geometry is nested only through regular drawing composite (for example, if the DrawingGroup contains a rectangle with a VisualBrush encapsulates a DrawingVisual, the content of that DrawingVisual will be antialiased even if you used that method).
Thus you can rewrite your code as follows:
DrawingVisual visual = new DrawingVisual();
DrawingGroup group = new DrawingGroup();
Pen pen = new Pen(Brushes.Black, 1);
group.Children.Add(new GeometryDrawing(Brushes.YellowGreen, pen, new EllipseGeometry(new Point(0,0), 40, 40)));
for (int i = 0; i <= 100 - 1; i++)
group.Children.Add(new GeometryDrawing(null, new Pen(Brushes.Black, 1), new LineGeometry(new Point(0, i), new Point(i, i))));
RenderOptions.SetEdgeMode(group, EdgeMode.Aliased);
DrawingContext context = visual.RenderOpen();
context.DrawDrawing(group);
context.Close();
RenderTargetBitmap bmp = new RenderTargetBitmap(100, 100, 96, 96, PixelFormats.Pbgra32);
bmp.Render(visual);
image1.Source = bmp;
The code You posted is drawing mutliple thin lines next to each other. Each of them is antialiased and has got its sides blurred. I suppose the opacity mixing effect You described occurs because of this.
If you drew one thick line (i.e. with 10 width) the effect would not appear.
So, the solution depends on what exactly You are trying to achieve:
new Pen(Brushes.Black, 2)
for (int i = 0; i <= 100 - 1; i++)
with for (float i = 0.0f; i <= 100 - 1; i+=0.5f)
.If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With