如何在 WPF 中多次旋转图像

Posted

技术标签:

【中文标题】如何在 WPF 中多次旋转图像【英文标题】:How to rotate image more than once in WPF 【发布时间】:2016-05-18 16:27:24 【问题描述】:

我打开了一个带有打开文件对话框的图像。

image.Source = new BitmapImage(new Uri(ofd.FileName));

然后我想旋转多少次,最后保存修改后的图像。问题是来自 MSDN 的代码:

var biOriginal = (BitmapImage)image.Source;
var biRotated = new BitmapImage();
biRotated.BeginInit();
biRotated.UriSource = biOriginal.UriSource;
biRotated.Rotation = Rotation.Rotate90;
biRotated.EndInit();
image.Source = biRotated;

我可以旋转图像,但只能旋转一次,并且无法保存旋转后的图像。

【问题讨论】:

Saving a BitmapImage 和 rotate by angle (或者如果您想要不止一次旋转,请在循环中重复您的代码) 由于异常无法像那样旋转无法将“System.Windows.Media.Imaging.BitmapImage”类型的对象转换为“System.Windows.Media.Imaging.TransformedBitmap”类型。 【参考方案1】:

如果我没记错的话,你只需要旋转图像。您可以通过对 XAML 中的 Image 元素应用布局转换并在单击按钮时更改其(转换的)角度值来做到这一点。此外,您似乎没有关注 MVVM。如果你这样做了,看看它有多简单:

查看

<Image Source="C:\Users\Public\Pictures\Sample Pictures\Penguins.jpg" 
    HorizontalAlignment="Center" VerticalAlignment="Center" Width="125">
        <Image.LayoutTransform>
            <RotateTransform Angle="Binding RotateAngle" />
        </Image.LayoutTransform>
</Image>
<Button Content="Rotate" Command="Binding RotateCommand" 
    VerticalAlignment="Bottom" HorizontalAlignment="Center" />

视图模型

public class ViewModel : BaseViewModel

    private ICommand rotateCommand;
    private double rotateAngle;

    public ICommand RotateCommand
    
        get
        
            if(rotateCommand == null)
            
                rotateCommand = new RelayCommand(() => 
                    RotateAngle += 90;
                );
            

            return rotateCommand;
        
    

    public double RotateAngle
    
        get
        
            return rotateAngle;
        

        private set
        
            if(value != rotateAngle)
            
                rotateAngle = value;
                OnPropertyChanged("RotateAngle");
            
        
    

查看代码隐藏

ViewModel vm;

public View()

    InitializeComponent();
    vm = new ViewModel();
    DataContext = vm;

我假设您不是 MVVM/WPF 的绝对初学者,并且省略了 BaseViewModel(实现 INotifyPropertyChanged)和 RelayCommand(实现 ICommand)的定义,因为我不想回答太冗长。如果您在这些方面遇到问题,请告诉我,我会将它们包括在此处。

【讨论】:

【参考方案2】:

以下代码似乎有效:

            BitmapImage newImage = new BitmapImage();
        newImage.BeginInit();
        newImage.UriSource = MyImage.UriSource;
        newImage.Rotation = Rotation.Rotate90;
        newImage.EndInit();
        JpegBitmapEncoder encoder = new JpegBitmapEncoder();
        string ImageName = Path.Combine( Environment.GetFolderPath(Environment.SpecialFolder.MyPictures), (Guid.NewGuid() + ".jpg"));
        encoder.Frames.Add(BitmapFrame.Create(newImage));

        using (var filestream = new FileStream(ImageName, FileMode.Create))
            encoder.Save(filestream);
        MyImage = new BitmapImage(new Uri(ImageName));

当然,每次旋转它都会创建一个新图像,如果你想多次旋转图像并只保存一次我还没有找到一种简单的方法来进行多次旋转而不保存旋转的图像。

【讨论】:

以上是关于如何在 WPF 中多次旋转图像的主要内容,如果未能解决你的问题,请参考以下文章

C#的WPF程序,如何使Canvas有旋转效果

从 WPF 中的图像裁剪对角线区域

从 WPF 中的图像裁剪对角线区域

随着窗口大小的变化,如何在wpf中动态测量网格宽度/高度

WPF 裁剪问题

如何实现WPF窗体旋转