Deathspike
Deathspike

Reputation: 8770

Horizontal image scaling with ScaleTransform in WPF

I have an image in a WPF window with the default Stretch setting, Uniform, and am making an attempt to make it fill the screen horizontally. I do not wish to use a different Stretch setting as this is supposed to a learning experience. The image dimensions being loaded are 420x800. This is the XAML for the window..

<Window x:Class="WpfApplication1.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Background="Red" Height="1200" Width="840">
    <Image Name="Image" Source="{Binding SourceUri}">
        <Image.RenderTransform>
            <TransformGroup>
                <ScaleTransform x:Name="Scale" />
                <TranslateTransform x:Name="Translate" />
            </TransformGroup>
        </Image.RenderTransform>
    </Image>
</Window>

On the code-behind, I am attempting to calculate the scaling to zoom the image to fill the horizontal screen and I am using translate transform the move it to the center of the screen. The following bit of code is obviously wrong...

using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;

namespace WpfApplication1 {
    public partial class MainWindow : Window {
        public MainWindow() {
            InitializeComponent();
            DataContext = this;

            double ImageWidth = 420;

            Scale.ScaleX = Width / ImageWidth;

            Translate.X = -(ImageWidth / 2);
        }

        public string SourceUri {
            get {
                return @"C:\Users\Roel\Desktop\test.png";
            }
        }
    }
}

I am attempting to understand how stretching and transformations are working together but I am having difficulty with this. I would appreciate all insights, even references to detailed explanations, as I have trouble finding any informational source explaining clearly and concisely how the transformations are applied.

Upvotes: 0

Views: 12191

Answers (1)

Clemens
Clemens

Reputation: 128061

You would usually just do this:

<Image Name="Image" Source="{Binding SourceUri}" Stretch="Fill"/>

In case you really need to calculate the stretch transformation manually, you would only need a ScaleTransform, no TranslateTransform, and you would put that into the LayoutTransform of the Image control. Moreover, the Image control would have to be placed into a Grid, which provides the size of the Windows's "client area". You can't calculate anything based on the Window's Width (or ActualWidth) as that includes the width of the Window's borders.

<Grid SizeChanged="Grid_SizeChanged">
    <Image Name="image" Source="{Binding SourceUri}">
        <Image.LayoutTransform>
            <ScaleTransform x:Name="scale"/>
        </Image.LayoutTransform>
    </Image>
</Grid>

In the Grid's SizeChanged handler you would calculate the scaling as shown below.

private void Grid_SizeChanged(object sender, SizeChangedEventArgs e)
{
    scale.ScaleX = e.NewSize.Width / image.Source.Width;
    scale.ScaleY = e.NewSize.Height / image.Source.Height;
}

Upvotes: 2

Related Questions