0

Is it possible to turn off anti-aliasing in WPF when using an ImageBrush?

Given the following code:

var handleImage = new BitmapImage(new Uri($"pack://application:,,,/Resources/myimage.png"));
var imageBrush = new ImageBrush(handleImage);
imageBrush.AlignmentY = AlignmentY.Top;
imageBrush.AlignmentX = AlignmentX.Left;
imageBrush.Stretch = Stretch.Uniform;
imageBrush.Viewport = new Rect(0, 0, _handleImage.Width, _handleImage.Height);
imageBrush.ViewportUnits = BrushMappingMode.Absolute;
imageBrush.TileMode = TileMode.Tile;
drawingContext.DrawRectangle(imageBrush, null, new Rect(0, 0, width, height));

Gives me something like: WPF Output

But I'm expecting: Expected Output

WPF's default antialiasing makes it look terrible. I've tried UseLayoutRounding=true, SnapsToDevicePixels=true, RenderOptions.SetBitmapScalingMode(this, BitmapScalingMode.HighQuality), RenderOptions.SetBitmapScalingMode(this, BitmapScalingMode.NearestNeighbor) RenderOptions.SetEdgeMode(this, EdgeMode.Unspecified); on the window. The only one that changes any visual difference is BitmapScalingMode.NearestNeighbor however it still looks odd and the tiling overlaps itself.

EDIT: Download full working sample: WpfImageBrushExample.zip

Michael Brown
  • 1,585
  • 1
  • 22
  • 36
  • Trying this just now, I don't see any problem, which suggests it's something else you haven't included. I would try setting `RenderOptions.EdgeMode` to `EdgeMode.Alias`, and if that doesn't work try posting an [MCVE](https://stackoverflow.com/help/minimal-reproducible-example). – Mark Feldman May 27 '20 at 22:02
  • Yup I can do that - I’ve also tried setting that as well but none of the options seem to affect the brush – Michael Brown May 28 '20 at 04:45
  • @MarkFeldman Full example added showing the drawing on any of the specified options mentioned in the post. – Michael Brown May 28 '20 at 22:19
  • The problem was two-fold: The `_handleImage` dimensions are supposed to be 4 x 5 but was returned as `5.333 x 6.66`. I need to use PixelWidth x PixelHeight and not Width x Height. Second, the `NearestNeighbor` scaling mode solves the problem once that is fixed! I'll answer my own question – Michael Brown May 28 '20 at 22:31
  • Glad to hear you solved it. And thanks for posting what it was, I wouldn't have thought a non-integer width or height would have done that? Something to keep an eye out for in future. – Mark Feldman May 28 '20 at 22:54

1 Answers1

0

The problem here was that the BitmapImage width and height were different fractional numbers - in this case it was 5.333 x 6x666 instead of the expected 4 x 5 pixels. If I use _handleImage.PixelWidth and _handleImage.PixelHeight the problem is fixed and I don't get weird aliasing under any of those rendering options set.

var handleImage = new BitmapImage(new Uri($"pack://application:,,,/Resources/myimage.png"));
var imageBrush = new ImageBrush(handleImage);
imageBrush.AlignmentY = AlignmentY.Top;
imageBrush.AlignmentX = AlignmentX.Left;
imageBrush.Stretch = Stretch.Uniform;
imageBrush.Viewport = new Rect(0, 0, _handleImage.PixelWidth, _handleImage.PixelHeight);
imageBrush.ViewportUnits = BrushMappingMode.Absolute;
imageBrush.TileMode = TileMode.Tile;
drawingContext.DrawRectangle(imageBrush, null, new Rect(0, 0, width, height));

Produces: Expected

Michael Brown
  • 1,585
  • 1
  • 22
  • 36