0

Ok, I've created a PNG-24 with transparency. It's basically a grayscale image that uses 'colors' in between black and transparent instead of black and white. I did this so I can use this as the Opacity Mask of a colored rectangle, thus rendering the image in whatever color I want using only a single graphic.

However, for the life of me, I can't get WPF to stop anti-aliasing the da*n image!!

I've set 'SnapesToDevicePixels' on the rectangle to which the brush is applied... I've set the ImageBrush's Scale to 'None'... I've set its ViewPort and the ViewBox to absolute units and sized them exactly to the source image. But no matter what I try, WPF still insists on trying to smooth things out! This is VERY frustrating!!!

So... anyone know how to use an image as an opacity mask but not lose the pixel-precise drawing that we have done? I just want WPF to render the damn thing as we drew it, period!

Mark A. Donohoe
  • 28,442
  • 25
  • 137
  • 286
  • Please post your code, from experience there's probably an elephant in the room that you can't see and that someone else will spot the moment they look at your code otherwise you are likely to running in circles here. – Lazarus Apr 07 '11 at 09:02
  • @MarquelV: Then you don't think that issue could be higher in the object tree? – Lazarus Apr 07 '11 at 09:51
  • It's one line of code... a simple ImageBrush set as the opacity mask of a rectangle with a solid fill. (Ok... two if you include the rectangle as well.) There are no elephants anywhere. The image is fine too. I've opened it up in several programs as well as using screen magnifiers to ensure I didn't barf something in Photoshop. It's fine. But WPF is still 'enhancing' the edges of my intentionally-jaggy image but only when used as a brush. I don't see any pixel-alignment-related things that I can set on the brush either. – Mark A. Donohoe Apr 07 '11 at 09:54
  • Sorry... I edited that by cutting-copying and it put this out of order. As for the visual tree... again... it is *just* a rectangle and an image brush. That is the root control of my test window. When I remove the opacity mask, the rectangle is dead-on to the pixel the same size as the image I'm using (since I set it's SnapsToDevicePixels and its Horizontal and Vertical alignments to top-left) so I know it's not that either. Add the opacity mask, BAM... anti-aliased mask. – Mark A. Donohoe Apr 07 '11 at 09:57
  • Can *you* show me an example that you know works? Create a diamond image (say 16x16) that just uses black and transparent. Nothing else. Load it into an imagebrush that you've set the Viewport and ViewBox to 0,0,16,16 and Absolute units for both and with a TileMode of None and a Stretch also of none... set that as the OpacityMask for a rectangle set at 16x16 with SnapsToDevicePixels and you'll still get that damn image anti-aliased. – Mark A. Donohoe Apr 07 '11 at 10:01
  • That wasn't an attack or rhetorical. It was literally a question. Can you? I haven't been able to figure it out and I'm stuck here. If I can't figure this out, I'm going to have to resort to manually creating graphics for each color that the app may use (six colors (so far!) times 20 graphics) which becomes a nightmare resource-wise. I can't believe there isn't the ability to paint with a brush that uses device pixels. – Mark A. Donohoe Apr 07 '11 at 10:10
  • @MarquelV: I'm not in a position at the moment do generate any code but I would if I could. I didn't see your response as an attack, I was actually answering your earlier comment and our submissions crossed I think ;) – Lazarus Apr 07 '11 at 10:27
  • Hi, if it's one line of code, can you post the line instead of writing three lines explaining that it's only one line of code? Sorry to be tetchy but that's quite annoying. Second provide the image, put it on imgur or a file sharing site or something, finally try and reproduce the situation on a new WPF project with the minimum of controls and code and post that if it still doesn't work. – Ian Apr 07 '11 at 13:25

2 Answers2

2

I have tried to reproduce your problem. Simply like this:

        <Rectangle Width="200" Height="200" Fill="Red">
            <Rectangle.OpacityMask>
                <ImageBrush ImageSource="/mask.png"/>
            </Rectangle.OpacityMask>
        </Rectangle>

mask.png contains a simple diagonal mask, like that half of rectange is visible and other half is 100% transparent. And recrangle is rendering pixel perfect (and aliased, as you want). I think, that you may a DPI setting, that is not native to your monitor, and WPF just can`t render images correctly.

Vladimir Perevalov
  • 4,059
  • 18
  • 22
  • That's the exact code that we have and it is adding 'blurring' for us, but ONLY when used as a brush. It's also a native-resolution LCD with the proper DPI so it's not that either. Is your diagonal line a perfect diagonal that only has black and transparent pixels in the source? Are you getting ONLY 100% opaque and 100% transparent in your output? Again, we get that perfectly when we use the image directly, but not when we use it as a brush. – Mark A. Donohoe Apr 07 '11 at 15:18
  • I know this is old, but two more years of WPF knowledge under my belt, I think I misunderstood your response. The DPI issue may have been with the graphic itself not being set to 96 DPI. Photoshop defaults to 72 and some designers forget to change that. Still, not sure how UseLayoutRounding would have fixed that, but if nothing else, I'm voting this up so others too can see this as a possible reason/cause. – Mark A. Donohoe Oct 09 '13 at 23:36
1

GOT IT! It's a layout issue that for some reason, there's no easy way to change. However, there's a value you can set called UseLayoutRounding that fixes it. I just set it at the root level (for this fauxample, a grid...)

<Grid UseLayoutRounding="True">
    ....
</Grid>

...and BAM! Works like a charm! "Sort of" like a 'SnapsToDevicePixels' but for positioning of elements (i.e. it rounds all layout-related values like left, width, etc. whereas SnapsToDevicePixels snaps the layout to the on-screen pixels when rendering.)

M

Mark A. Donohoe
  • 28,442
  • 25
  • 137
  • 286