WPF中如何翻转图像

54

最近我学会了如何使用'TransformedBitmap'和'RotateTransformed'类旋转一个BitmapImage。现在我能够对我的图像进行顺时针旋转。但是我该如何翻转一张图片呢?我找不到能够对一个BitmapImage进行水平和垂直翻转的类。请帮我找出如何完成这个任务的方法。例如,如果我的图片是一个看起来像'd'的图形,那么垂直翻转将会得到像'q'一样的东西,而水平翻转将会得到像'b'一样的东西。

6个回答

132

使用ScaleTransform,其中ScaleX为-1表示水平翻转,ScaleY为-1表示垂直翻转,应用于图像的RenderTransform属性。在图像上使用RenderTransformOrigin="0.5,0.5"可以确保图像围绕其中心翻转,因此您不必应用其他的TranslateTransform来移动它到正确的位置:

<Image Source="a.jpg" Padding="5" RenderTransformOrigin="0.5,0.5">
  <Image.RenderTransform>
    <ScaleTransform ScaleX="-1"/>
  </Image.RenderTransform>
</Image>

用于水平翻转

<Image Source="a.jpg" Padding="5" RenderTransformOrigin="0.5,0.5">
  <Image.RenderTransform>
    <ScaleTransform ScaleY="-1"/>
  </Image.RenderTransform>
</Image>

用于垂直方向。

如果想要在代码后台实现,在C#中应该类似于以下代码:

img.RenderTransformOrigin = new Point(0.5,0.5);
ScaleTransform flipTrans = new ScaleTransform();
flipTrans.ScaleX = -1;
//flipTrans.ScaleY = -1;
img.RenderTransform = flipTrans;

如何翻转 BitmapFrame - techno

9
为了让翻转效果更加逼真,您可以使用较小的比例变换进行斜切变换。您需要将对象斜切约20度,以使其看起来像是在3D空间中翻转。这是一种简单的3D翻转方法。您也可以在WPF中实现真正的3D翻转,但需要更多的工作。这将为您提供更清晰的动画效果,然后您可以在两个不同的面板之间切换可见性,从而给您的元素带来正反两面的印象。
<DoubleAnimationUsingKeyFrames Storyboard.TargetName="MyControl" Storyboard.TargetProperty="(FrameworkElement.RenderTransform).(TransformGroup.Children)[0].(ScaleTransform.ScaleX)">
  <SplineDoubleKeyFrame KeyTime="00:00:00.0" Value="1" />
  <SplineDoubleKeyFrame KeyTime="00:00:00.09" Value="0.3" />
  <SplineDoubleKeyFrame KeyTime="00:00:00.12" Value="0.6" />                              
  <SplineDoubleKeyFrame KeyTime="00:00:00.15" Value="0.8" />
  <SplineDoubleKeyFrame KeyTime="00:00:00.18" Value="1" />
  <SplineDoubleKeyFrame KeyTime="00:00:00.2" Value="1" />
</DoubleAnimationUsingKeyFrames>

<DoubleAnimationUsingKeyFrames Storyboard.TargetName="MyControl" Storyboard.TargetProperty="(FrameworkElement.RenderTransform).(TransformGroup.Children)[0].(ScaleTransform.ScaleY)">
  <SplineDoubleKeyFrame KeyTime="00:00:00.0" Value="1" />
  <SplineDoubleKeyFrame KeyTime="00:00:00.09" Value="0.9" />
  <SplineDoubleKeyFrame KeyTime="00:00:00.18" Value="1" />
  <SplineDoubleKeyFrame KeyTime="00:00:00.2" Value="1" />
</DoubleAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames Storyboard.TargetName="MyControl" Storyboard.TargetProperty="(FrameworkElement.RenderTransform).(TransformGroup.Children)[1].(SkewTransform.AngleY)">
  <SplineDoubleKeyFrame KeyTime="00:00:00" Value="0" />
  <SplineDoubleKeyFrame KeyTime="00:00:00.06" Value="-10" />
  <SplineDoubleKeyFrame KeyTime="00:00:00.09" Value="-20" />
  <SplineDoubleKeyFrame KeyTime="00:00:00.1" Value="20" />
  <SplineDoubleKeyFrame KeyTime="00:00:00.18" Value="0" />
</DoubleAnimationUsingKeyFrames>

5
<Image x:Name="SampleImage"  Margin="0" RenderTransformOrigin="0.5,0.5" >
        <Image.LayoutTransform>
            <TransformGroup>
                <ScaleTransform ScaleY="1" ScaleX="-1"/>
                <SkewTransform AngleY="0" AngleX="0"/>
                <RotateTransform Angle="0"/>
                <TranslateTransform/>
            </TransformGroup>
        </Image.LayoutTransform>
    </Image>

创建一个像这样的图片组件。当设置了其来源时,该图片将从左向右翻转。

4

对于仅水平翻转的快速技巧是将FlowDirection属性设置为FlowDirection.RightToLeft。但如果组件是一个容器,它的一些子元素可能会以不同的方式解释该属性(自定义逻辑)。


这真的帮了我大忙,因为它可以翻转图像而不移动它。 - Tim Pohlmann
1
顺便说一下,如果你尝试使用x-scale的-1进行ScaleTransform时,如果它在移动,那么你可能会错过RenderTransformOrigin="0.5,0.5"。然而,在代码中(或者放在XAML中)使用FlowDirection确实更加直观易懂,而不是使用transforms方法。 - George Birbilis

2

要翻转容器控件,请查看 http://clipflair.codeplex.com,在 Client\ZUI 文件夹下的 FlipPanel 项目。 - George Birbilis

1

你可以使用带有负值的ScaleTransform来对ScaleX/ScaleY进行缩放:

  <TextBlock Text="P">
   <TextBlock.RenderTransform>
    <ScaleTransform ScaleY="-1" ScaleX="-1" />
   </TextBlock.RenderTransform>
  </TextBlock>

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接