WPF 任意角度旋转图像 [英] WPF Rotating image with arbitrary angle

查看:68
本文介绍了WPF 任意角度旋转图像的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图让 BitmapImage myImage1 和 myImage2 旋转到任意角度(可能是 45、30、10...等)

I am trying to make BitmapImage myImage1 and myImage2 rotate to an arbitrary angle (could be 45, 30, 10... etc.)

我得到的错误是我只能将它旋转到 90、180 或 270 度.

The error I'm getting is that I can only rotate it to 90, 180, or 270 degrees.

XAML 代码:

<Window x:Class="CSWPFAnimatedImage.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="WPF Animated Image Sample" Height="300" Width="300" Loaded="Window_Loaded">
<Window.Resources>
    <Storyboard x:Key="VisibleToInvisible" Completed="VisbleToInvisible_Completed" >
        <DoubleAnimation Storyboard.TargetName="TransparentStop"
                        Storyboard.TargetProperty="Offset" To="0"  Duration="0:0:2"   />
        <DoubleAnimation Storyboard.TargetName="BlackStop"
                        Storyboard.TargetProperty="Offset" To="0" Duration="0:0:2"
                        />
    </Storyboard>
    <Storyboard x:Key="InvisibleToVisible" Completed="InvisibleToVisible_Completed">
        <DoubleAnimation Storyboard.TargetName="TransparentStop"
                        Storyboard.TargetProperty="Offset" To="1"  Duration="0:0:2"   />
        <DoubleAnimation Storyboard.TargetName="BlackStop"
                        Storyboard.TargetProperty="Offset" To="1" Duration="0:0:2"   />
    </Storyboard>
</Window.Resources>
<Window.Triggers>
    <EventTrigger RoutedEvent="Window.Loaded">
        <EventTrigger.Actions>
            <BeginStoryboard Storyboard="{StaticResource  VisibleToInvisible}"/>
        </EventTrigger.Actions>
    </EventTrigger>
</Window.Triggers>
<Grid Name="grid">        
    <Image x:Name="myImage2" Source="Images/image2.jpg" />
    <Image x:Name="myImage1" Source="Images/image1.jpg">
        <Image.OpacityMask>
            <LinearGradientBrush StartPoint="0,0" EndPoint="1,0">
                <GradientStop Offset="1" Color="Black" x:Name="BlackStop"/>
                <GradientStop Offset="1" Color="Transparent" x:Name="TransparentStop"/>
            </LinearGradientBrush>
        </Image.OpacityMask>
    </Image>
</Grid> </Window>

这是C#中的代码:

using System;
using System.Collections.Generic;
using System.Windows;
using System.Windows.Media.Animation;
using System.Windows.Media.Imaging;

namespace CSWPFAnimatedImage
{
    /// <summary>
    /// Interaction logic for Window1.xaml
    /// </summary>
public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
    }

    int nextImageIndex;
    List<BitmapImage> images = new List<BitmapImage>();

    private void Window_Loaded(object sender, RoutedEventArgs e)
    {
        // Initialize the images collection
        images.Add(new BitmapImage(new Uri("Images/image1.jpg", UriKind.Relative)));
        images.Add(new BitmapImage(new Uri("Images/image2.jpg", UriKind.Relative)));
        images.Add(new BitmapImage(new Uri("Images/image3.jpg", UriKind.Relative)));
        images.Add(new BitmapImage(new Uri("Images/image4.jpg", UriKind.Relative)));

        nextImageIndex = 2;
    }

    private void VisbleToInvisible_Completed(object sender, EventArgs e)
    {
        // Change the source of the myImage1 to the next image to be shown
        // and increase the nextImageIndex
        this.myImage1.Source = images[nextImageIndex++];

        // If the nextImageIndex exceeds the top bound of the collection,
        // get it to 0 so as to show the first image next time
        if (nextImageIndex == images.Count)
        {
            nextImageIndex = 0;
        }

        // Get the InvisibleToVisible storyboard and start it
        Storyboard sb = this.FindResource("InvisibleToVisible") as Storyboard;
        sb.Begin(this);

    }

    private void InvisibleToVisible_Completed(object sender, EventArgs e)
    {
        // Change the source of the myImage2 to the next image to be shown
        // and increase the nextImageIndex
        this.myImage2.Source = images[nextImageIndex++];

        // If the nextImageIndex exceeds the top bound of the collection,
        // get it to 0 so as to show the first image next time
        if (nextImageIndex == images.Count)
        {
            nextImageIndex = 0;
        }

        // Get the VisibleToInvisible storyboard and start it
        Storyboard sb = this.FindResource("VisibleToInvisible") as Storyboard;
        sb.Begin(this);

        this.turnToAnyAngle(); // Make it rotate to angle set below
    }  

    private void turnToAnyAngle()
    {
        TransformedBitmap tb = new TransformedBitmap();

        var biRotated = new BitmapImage();
        biRotated.BeginInit();
        biRotated.UriSource = new Uri(@"INSERT_IMAGE_PATH_HERE", UriKind.RelativeOrAbsolute);
        biRotated.EndInit();

        tb.BeginInit();
        tb.Source = biRotated;
        RotateTransform transform = new RotateTransform();
        transform.Angle = 45;
        tb.Transform = transform;
        tb.EndInit();

        myImage2.Source = tb;

    }

}
}

在 C# 方法 turnToAnyAngle() 中,我收到以下错误:

In the C# method turnToAnyAngle() I get the following error:

System.InvalidOperationException"类型的未处理异常发生在 PresentationCore.dll 中

An unhandled exception of type 'System.InvalidOperationException' occurred in PresentationCore.dll

附加信息:变换必须是尺度的组合,翻转和 90 度旋转

Additional information: Transform must be a combination of scales, flips, and 90 degree rotations

我需要在不影响渲染的情况下旋转此图像,因此 rendertransform 不是可行的解决方案.

推荐答案

您只能使用 TransformedBitmap 以 90 度为增量旋转,请参阅 这里

You can only rotate in increments of 90 degrees using a TransformedBitmap see here

您应该做的是在 Image 控件(承载位图)上执行 RenderTranform,请参阅 这里

What you should be doing instead is perform a RenderTranform on the Image control (which hosts the bitmap) see here

这篇关于WPF 任意角度旋转图像的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆