user1202434
user1202434

Reputation: 2273

Apply zoom and also flipping to image wpf?

i have xaml defined for an image as follows:

 <ControlTemplate>
                <Grid>                  
                    <Image x:Name="documentPage" Source="{Binding ImageSource}"
                            VerticalAlignment="Stretch" HorizontalAlignment="Stretch" Stretch="Fill">    
                        <Image.LayoutTransform>
                            <TransformGroup>
                                <ScaleTransform ScaleX="{Binding ScaleFactor}" ScaleY="{Binding ScaleFactor}"/>
                            </TransformGroup>
                        </Image.LayoutTransform>
                    </Image>                     
                </Grid>
            </ControlTemplate>

and on buttons for zoom in and zoom out I increment the ScaleFactor by 0.1 (zoom in) or decrement by 0.1 (zoom out).

Now I also want to apply flipping the image as well...like flip it vertically or horizontally....How do I do that? Thanks!

Upvotes: 0

Views: 1114

Answers (1)

Andy
Andy

Reputation: 6466

Inside the TransformGroup that you've applied to LayoutTransform you can put as many scale transforms as you want, you could bind another scale transform to a property.

<Image.LayoutTransform>
    <TransformGroup>
      <ScaleTransform ScaleX="{Binding ScaleFactor}" ScaleY="{Binding ScaleFactor}"/>
      <ScaleTransform ScaleX="-1" ScaleY="1"/>
    </TransformGroup>
</Image.LayoutTransform>

instead of -1 and 1 in the second transform bind them to a property in your viewmodel (obviously a converter will be required if your flipx and flipy properties are boolean)

Here I've created a simple example that shows all of the features from your question using a converter to convert boolean properties into a scale transforms ScaleX and ScaleY.

enter image description here

XAML

  <Window x:Class="flipx.MainWindow"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            xmlns:local="clr-namespace:flipx"
            DataContext="{Binding RelativeSource={RelativeSource Self}}"
            Title="MainWindow" Height="350" Width="525">
        <Grid>
            <Grid.RowDefinitions>
                <RowDefinition Height="*"/>
                <RowDefinition Height="30"/>
            </Grid.RowDefinitions>
            <Ellipse Grid.Row="0"  Width="100" Height="100">
                <Ellipse.Fill>
                    <LinearGradientBrush >
                        <GradientStop Color="Red"/>
                        <GradientStop Color="#FF2300FF" Offset="1"/>
                    </LinearGradientBrush>
                </Ellipse.Fill>
                <Ellipse.LayoutTransform>
                    <TransformGroup>
                        <ScaleTransform ScaleX="{Binding ScaleFactor}" ScaleY="{Binding ScaleFactor}"/>
                        <ScaleTransform ScaleX="{Binding FlipX, Converter={local:BooleanToScaleConverter}}" ScaleY="{Binding FlipY, Converter={local:BooleanToScaleConverter}}"/>
                    </TransformGroup>
                </Ellipse.LayoutTransform>
            </Ellipse>

            <StackPanel Grid.Row="1" Orientation="Horizontal" HorizontalAlignment="Center">
                <CheckBox Margin="5" IsChecked="{Binding FlipX}">FlipX</CheckBox>
                <CheckBox Margin="5" IsChecked="{Binding FlipY}">FlipY</CheckBox>         
                <Slider Minimum="0.001" Maximum="5" Value="{Binding ScaleFactor}" Width="150"/>
            </StackPanel>
        </Grid>

    </Window>

C#

using System;
using System.Windows;
using System.Windows.Data;
using System.Windows.Markup;

namespace flipx
{
    public class BooleanToScaleConverter : MarkupExtension, IValueConverter
    {
        static BooleanToScaleConverter converter;

        public BooleanToScaleConverter() { }

        public override object ProvideValue(IServiceProvider serviceProvider)
        {
            if (converter == null) converter = new BooleanToScaleConverter();
            return converter;
        }

        public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            bool boolValue = (bool)value;
            return boolValue ? -1 : 1;
        }

        public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            throw new NotImplementedException();
        }
    }

    public partial class MainWindow : Window
    {
        public double ScaleFactor
        {
            get { return (double)GetValue(ScaleFactorProperty); }
            set { SetValue(ScaleFactorProperty, value); }
        }
        public static readonly DependencyProperty ScaleFactorProperty =
            DependencyProperty.Register("ScaleFactor", typeof(double), typeof(MainWindow), new PropertyMetadata(1d));

        public bool FlipX
        {
            get { return (bool)GetValue(FlipXProperty); }
            set { SetValue(FlipXProperty, value); }
        }
        public static readonly DependencyProperty FlipXProperty =
            DependencyProperty.Register("FlipX", typeof(bool), typeof(MainWindow), new PropertyMetadata(false));

        public bool FlipY
        {
            get { return (bool)GetValue(FlipYProperty); }
            set { SetValue(FlipYProperty, value); }
        }        
        public static readonly DependencyProperty FlipYProperty =
            DependencyProperty.Register("FlipY", typeof(bool), typeof(MainWindow), new PropertyMetadata(false));

        public MainWindow()
        {
            InitializeComponent();
        }
    }
}

Upvotes: 4

Related Questions