AvaloniaUI / Avalonia

Develop Desktop, Embedded, Mobile and WebAssembly apps with C# and XAML. The most popular .NET UI client technology
https://avaloniaui.net
MIT License
25.8k stars 2.23k forks source link

Allow Anti-Aliasing to be disabled #7915

Closed kolbyd closed 1 year ago

kolbyd commented 2 years ago

Is your feature request related to a problem? Please describe. A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]

Drawing 1-pixel thick lines results in blurry, fuzzy outputs while using DrawingContext.DrawLine(). image I believe this is due to anti-aliasing.

Describe the solution you'd like A clear and concise description of what you want to happen.

A way to disable anti-aliasing for the drawing context (which I believe is included in native WPF).

Describe alternatives you've considered A clear and concise description of any alternative solutions or features you've considered.

Right now, I can add 0.5 to all my x,y values to prevent this behavior. image

But this is less than ideal as I can't add a centre line through the square without it being blurred.

Additional context Add any other context or screenshots about the feature request here.

Blurry lines:

public void Draw(double x, double y, DrawingContext drawingContext)
{
    Pen _pen = new(new SolidColorBrush(Color.FromRgb(202, 205, 169)));

    List<Point> Points = new List<Point>()
    {
        new Point(x - 4, y - 4),
        new Point(x + 4, y - 4),
        new Point(x + 4, y + 4),
        new Point(x - 4, y + 4),
        new Point(x - 4, y - 4),
    };

    for (int i = 0; i < Points.Count - 1; i++)
    {
        drawingContext.DrawLine(_pen, Points[i], Points[i + 1]);
    }
}

Non-blurry lines:

public void Draw(double x, double y, DrawingContext drawingContext)
{
    Pen _pen = new(new SolidColorBrush(Color.FromRgb(202, 205, 169)));

    List<Point> Points = new List<Point>()
    {
        new Point(x - 4.5, y - 4.5),
        new Point(x + 4.5, y - 4.5),
        new Point(x + 4.5, y + 4.5),
        new Point(x - 4.5, y + 4.5),
        new Point(x - 4.5, y - 4.5),
    };

    for (int i = 0; i < Points.Count - 1; i++)
    {
        drawingContext.DrawLine(_pen, Points[i], Points[i + 1]);
    }
}
HoneyTauOverTwo commented 2 years ago

I guess this one is related to a problem I came across... I initialized a 200x200 pixel WriteableBitmap with 4 colors, I did not want a blurry edge between them. I assume anti-aliasing is doing the same here: anti-aliasing on (this is a crop of the transition region)

But in this case it would be a property on Image instead of DrawingContext.

maxkatz6 commented 2 years ago

@kolbyd @HoneyTauOverTwo you can set RenderOptions.BitmapInterpolationMode property:

<Image Source="{Binding MyBitmap}" RenderOptions.BitmapInterpolationMode="LowQuality" />

It has quite confusing naming for enum values, because we copied Skia naming. https://github.com/AvaloniaUI/Avalonia/blob/d1afd3bb591c266015dcdecc9611148ca08c2ee4/src/Skia/Avalonia.Skia/SkiaSharpExtensions.cs#L16 https://github.com/AvaloniaUI/Avalonia/blob/4c77f1eb3d11308412b915a82460e4408ce360a0/src/Windows/Avalonia.Direct2D1/Media/Imaging/WicBitmapImpl.cs#L28

HoneyTauOverTwo commented 2 years ago

@maxkatz6 I was digging into Avalonia's code and found this BitmapInterpolationMode enum. But did not find where to set it yet.

I changed my code to this (I am not using data bindings):

<Image x:Name="DisplayImage" RenderOptions.BitmapInterpolationMode="LowQuality"/>

Then in the code behind I have:

WriteableBitmap bmp = new WriteableBitmap(new PixelSize(200, 200), new Vector(96, 96));
// bmp initialization omitted
DisplayImage.Source = bmp;

but it still produces the same result. And sorry for cluttering this here, probably not the place to discuss.

kolbyd commented 2 years ago

Related to #199

Hanprogramer commented 1 year ago

Is there a way to do this from C#? Couldn't find the property

timunie commented 1 year ago

@Hanprogramer If I understood correctly there is currently no easy easy to do. As you can see the issue is also still open. There is a PR to implement this, see #9584 . You may want to try this PR out and see if your issue is resolved.