31

I have a little problem, I have a group item which I want to give a background image which it should scale keeping it's correct dimensions but by default it shows the image from the top left, I want the image to be centered.

Here is an illustration to further explain my problem. (the gray part is what is clipped)

My problem

And I have this XAML

<Image Source="/url/to/image.jpg" Stretch="UniformToFill"/>
Mats Hofman
  • 7,060
  • 6
  • 33
  • 48

3 Answers3

19

I managed to solve my problem, I made the image larger than the container it was placed in and vertical aligned it in the center.

<Grid HorizontalAlignment="Left" Width="250" Height="125">
    <Image Source="/url/to/image.jpg" Stretch="UniformToFill" Height="250" Margin="0" VerticalAlignment="Center"/>
</Grid>

The overflow of the image was invisible :)

Mats Hofman
  • 7,060
  • 6
  • 33
  • 48
  • Sorry just got on and saw your msg and was going to load it up to test bu ya that's what I was missing, telling it to do exactly that. If you lose resolution though try the same thing with it plopped in a ViewBox. Glad you got your remedy, remember to mark it as answered. Cheers :) – Chris W. Nov 25 '12 at 20:32
7

In case the size of the source image is unknown in advance I had to use different trick:

<Border Width="250" Height="250">
    <Border.Background>
        <ImageBrush ImageSource="/url/to/image.jpg"
                    Stretch="UniformToFill"/>
    </Border.Background>
</Border>
aguyngueran
  • 1,301
  • 10
  • 23
3

I wrote a behavior for Silverlight/Windows Phone that treats a similar situation. The picture I have to show may be larger or higher and I must display it in a square.

The behavior calculates the width/height ratio of both the container and the picture. Depending on which is the largest/highest, I resize the Image control to have this clipping effect with the parent control.

Here is a sample XAML to use with my behavior.

<Border Height="150" Width="150">
    <Image Source="{Binding BitmapImage}" Stretch="UniformToFill"
            HorizontalAlignment="Center" VerticalAlignment="Center">
        <i:Interaction.Behaviors>
            <b:FillParentBehavior />
        </i:Interaction.Behaviors>
    </Image>
</Border>

Here is an excerpt from the C# code. The full code can be found here: FillParentBehavior.cs

double width = this.AssociatedObject.Width;
double height = this.AssociatedObject.Height;
var parentSize = new Size(this.parent.ActualWidth, this.parent.ActualHeight);
var parentRatio = parentSize.Width / parentSize.Height;

// determine optimal size
if (this.AssociatedObject is Image)
{
    var image = (Image)this.AssociatedObject;
    if (image.Source is BitmapImage)
    {
        var bitmap = (BitmapImage)image.Source;
        var imageSize = new Size(bitmap.PixelWidth, bitmap.PixelHeight);
        var imageRatio = imageSize.Width / imageSize.Height;
        if (parentRatio <= imageRatio)
        {
            // picture has a greater width than necessary
            // use its height
            width = double.NaN;
            height = parentSize.Height;
        }
        else
        {
            // picture has a greater height than necessary
            // use its width
            width = parentSize.Width;
            height = double.NaN;
        }
    }
}

this.AssociatedObject.Width = width;
this.AssociatedObject.Height = height;
SandRock
  • 5,276
  • 3
  • 30
  • 49