105

I have a problem with displaying images in WPF.

Here's my code:

<Button HorizontalAlignment="Left" Grid.Column="1" Grid.Row="5" Margin="0,5">
        <Button.Content>
            <StackPanel Orientation="Horizontal" Margin="10,0">
                <Image Source="/images/user_add.png" Stretch="None" HorizontalAlignment="Center" VerticalAlignment="Center" Width="24" Height="24" />
                <TextBlock Text="添加" />
            </StackPanel>
        </Button.Content>
    </Button>

I have an image with original size 32*32, but when I ran the above code, the image will stretch to fill all the space, beyond its original size. I also set the "Stretch" property to "None", but it seems that it doesn't work.

So, how can I fix this problem? Thank you!

dthrasher
  • 40,656
  • 34
  • 113
  • 139
jiluo
  • 2,296
  • 3
  • 21
  • 34
  • Verify the image DPI by displaying the following columns in the _Windows File Explorer_: `Horizontal Resolution` and `Vertical Resolution`. – Pressacco Apr 10 '21 at 13:47

5 Answers5

134

Here is a similar question. Generally setting Stretch="None" is enough.

It is also very important what DPI has the image set in metadata. It took me quite a while before figuring out that if the image's DPI is different from the monitor's DPI (usually 96), WPF will automatically resize the image, as it tries to be DPI-independent.


EDIT

The MSDN link is broken, here is the new link: MSDN Blog - Blurry Bitmaps. Let's keep the old link around to be used for archive.org, in case the new link stops working also.

Paya
  • 5,124
  • 4
  • 45
  • 71
  • 10
    Great tip regarding DPI settings, Paja. Several of my toolbar icons had been set to 72 DPI, which causes them to appear larger even if the pixel dimensions are 16x16. – dthrasher Mar 14 '11 at 00:21
  • 1
    I don't understand. Are you saying WPF will layout your window differently depending on the resolution of the screen? There's no way that could possibly be a good thing. – Kyle Delaney Apr 18 '17 at 15:49
  • @KyleDelaney Have you read the article I linked in the answer? – Paya Apr 19 '17 at 18:52
  • Yes, and I'm asking for clarification on it. – Kyle Delaney Apr 19 '17 at 19:28
  • @KyleDelaney Yes, WPF takes into account the DPI of your screen when rendering. Your controls and images will have (almost) the same physical size on different monitors with different DPIs. It's actually a good thing, otherwise your controls on a 300 DPI monitor would be tiny and text barely readable. It's the correct way to handle the issue of supporting screens with vastly different DPIs, and the same approach is used on smart phones. – Paya Apr 20 '17 at 22:10
  • So it's not just images but all controls? So the entire application gets scaled rather than just the images, and the relative sizes and the layout get preserved? – Kyle Delaney Apr 22 '17 at 01:03
  • 1
    @KyleDelaney Yes, that's also why you use "points" instead of "pixels" to specify sizes, distances, margins etc in WPF. – Paya Apr 24 '17 at 08:23
  • So, how to tell WPF to ignore the DPI and display image pixel to pixel? I think the link is broken – Paweł Audionysos Feb 01 '20 at 19:02
  • 1
    @PawełAudionysos I have fixed the broken link – Paya Feb 03 '20 at 04:14
7
<Image Source="Images/Background.png" UseLayoutRounding="True" SnapsToDevicePixels="True" Width="600" Height="800" Stretch="Fill" />

This one works for me, for an image with 600x800 pixels and 96dpi.

@rishad2m8 If size is unknown one can detect the size first with https://msdn.microsoft.com/en-us/library/system.drawing.image.size(v=vs.110).aspx I'd guess.

7

Try not specifying width or height, use it like this instead:

<Image Source="/images/user_add.png" Stretch="None" HorizontalAlignment="Center" VerticalAlignment="Center" />
VoodooChild
  • 9,776
  • 8
  • 66
  • 99
4

Adding to Paya's answer: to compensate WPF's attempt to adapt to the monitors resolution you should be able to set the Width and Height to the file's original dimensions and use Stretch="Fill". This worked for me.

A Coder
  • 3,039
  • 7
  • 58
  • 129
sorrymissjackson
  • 2,395
  • 1
  • 19
  • 18
0

If you want to display the image with original size, but don't know the image size, I think the best way is to set the image as background of UIElement. Like this:

    <Button Height="100" Width="100">
        <Button.Background>
            <ImageBrush ImageSource="/images/user_add.png" Stretch="None"/>
        </Button.Background>
    </Button>
shirley
  • 11
  • 6