C#学习--项目实战之隐藏式导航栏

C#学习--项目实战之隐藏式导航栏


最近在开发一个视觉工具项目。突发奇想,想写一个隐藏式的导航栏,对处理过的图片做一个记录,并保存在导航栏中,点击对应的位置,可以唤出对应的图片。

界面展示

设计器界面
在这里插入图片描述
实际界面
在这里插入图片描述

代码

View.xaml
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="2.5*"/>
            <RowDefinition/>
        </Grid.RowDefinitions>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="3*"/>
            <ColumnDefinition/>
        </Grid.ColumnDefinitions>

        <Grid Name="ImageG" Grid.Column="0" Grid.Row="0">
            <Border Name="BtnBo" HorizontalAlignment="Left" Width="15" Height="100" BorderThickness="0" Background="#7FBEF0F6" MouseEnter="HideMenu_MouseEnter">
                <Image Source="../Resource/Image/menu0.png" Height="50"></Image>
            </Border>

            <Border Name="HideMenu" Background="#7FBEF0F6" MouseLeave="HideMenu_MouseLeave" Width="100" HorizontalAlignment="Left" Margin="-100 0 0 0">
                <ListBox Background="{x:Null}" ItemsSource="{Binding ImageList}" SelectedItem="{Binding ImageSelected}" BorderThickness="0" SelectedIndex="{Binding ImageIndex}">
                    <ListBox.ItemTemplate>
                        <DataTemplate>
                            <StackPanel Orientation="Horizontal">
                                <Image Source="{Binding Image}" Width="35"></Image>
                                <Label Content="{Binding Tag}" FontSize="10" HorizontalAlignment="Center" VerticalAlignment="Center"></Label>
                            </StackPanel>
                        </DataTemplate>
                    </ListBox.ItemTemplate>
                </ListBox>
            </Border>

            <Image Source="{Binding ImageSource}" Margin="5"></Image>

            <Border Background="#66EDF1CC" Width="80" HorizontalAlignment="Right">
                <Grid>
                    <Grid.RowDefinitions>
                        <RowDefinition/>
                        <RowDefinition/>
                        <RowDefinition/>
                    </Grid.RowDefinitions>
                    <Label Grid.Row="0" Content="图像信息" VerticalAlignment="Top" HorizontalAlignment="Center"></Label>
                    <TextBlock Grid.Row="1" Text="{Binding SrcImage.Rows}" VerticalAlignment="Center" HorizontalAlignment="Center"></TextBlock>
                    <TextBlock Grid.Row="2" Text="{Binding SrcImage.Cols}" VerticalAlignment="Center" HorizontalAlignment="Center"></TextBlock>
                </Grid>
            </Border>
        </Grid>

        <GroupBox Header="Log" Grid.Column="0" Grid.Row="1" Margin="5">
            <ScrollViewer>
                <TextBlock Name="LogContent" Text="{Binding LogContent}" ScrollViewer.CanContentScroll="True"></TextBlock>
            </ScrollViewer>
        </GroupBox>

        <Grid Grid.Row="0" Grid.Column="1">
            <Grid.ColumnDefinitions>
                <ColumnDefinition/>
                <ColumnDefinition/>
            </Grid.ColumnDefinitions>
            <Grid.RowDefinitions>
                <RowDefinition/>
                <RowDefinition/>
                <RowDefinition/>
                <RowDefinition/>
                <RowDefinition/>
            </Grid.RowDefinitions>
            
            <Button Grid.Column="0" Grid.Row="0" Margin="5" Content="清空图像" Command="{Binding ClearImageCommand}"></Button>
            <Button Grid.Column="1" Grid.Row="0" Margin="5" Content="加载图像" Command="{Binding LoadImageCommand}"></Button>

            <Button Grid.Column="0" Grid.Row="1" Margin="5" Content="平移" Command="{Binding TranslationCommand}"></Button>
            <Button Grid.Column="0" Grid.Row="2" Margin="5" Content="旋转" Command="{Binding RotateCommand}"></Button>
            <Button Grid.Column="0" Grid.Row="3" Margin="5" Content="放大" Command="{Binding BiggerCommand}"></Button>
            <Button Grid.Column="0" Grid.Row="4" Margin="5" Content="缩小" Command="{Binding SmallerCommand}"></Button>

            <Grid Grid.Column="1" Grid.Row="1">
                <Grid.RowDefinitions>
                    <RowDefinition/>
                    <RowDefinition/>
                </Grid.RowDefinitions>
                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="auto"/>
                    <ColumnDefinition/>
                </Grid.ColumnDefinitions>
                <Label Grid.Column="0" Grid.Row="0" Content="垂直"></Label>
                <TextBox Grid.Column="1" Grid.Row="0" Margin="1" Text="{Binding Vertical}" InputScope="Number"></TextBox>
                <Label Grid.Column="0" Grid.Row="1" Content="水平"></Label>
                <TextBox Grid.Column="1" Grid.Row="1" Margin="1" Text="{Binding Horizontal}" InputScope="Number"></TextBox>
            </Grid>

            <Grid Grid.Column="1" Grid.Row="2">
                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="auto"/>
                    <ColumnDefinition/>
                </Grid.ColumnDefinitions>
                <Label Grid.Column="0" Grid.Row="0" Content="角度" HorizontalAlignment="Center" VerticalAlignment="Center"></Label>
                <TextBox Grid.Column="1" Grid.Row="0" Margin="1 15 1 15" Text="{Binding Angle}" InputScope="Number"></TextBox>
            </Grid>

            <Grid Grid.Column="1" Grid.Row="3">
                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="auto"/>
                    <ColumnDefinition/>
                </Grid.ColumnDefinitions>
                <Label Grid.Column="0" Grid.Row="0" Content="倍数" HorizontalAlignment="Center" VerticalAlignment="Center"></Label>
                <TextBox Grid.Column="1" Grid.Row="0" Margin="1 15 1 15" Text="{Binding BigTimes}" InputScope="Number"></TextBox>
            </Grid>

            <Grid Grid.Column="1" Grid.Row="4">
                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="auto"/>
                    <ColumnDefinition/>
                </Grid.ColumnDefinitions>
                <Label Grid.Column="0" Grid.Row="0" Content="倍数" HorizontalAlignment="Center" VerticalAlignment="Center"></Label>
                <TextBox Grid.Column="1" Grid.Row="0" Margin="1 15 1 15" Text="{Binding SmalleTimes}" InputScope="Number"></TextBox>
            </Grid>
        </Grid>
    </Grid>
View.cs
public partial class AffineView : Window
    {
        private Storyboard mStoryboard0;
        private Storyboard mStoryboard1;
        private AffineViewModel viewmodel;
        private bool isShowedMenu = false;
        public AffineView()
        {
            InitializeComponent();

            viewmodel = new AffineViewModel();
            this.DataContext = viewmodel;
            InitAnimation();
            
        }

        private void InitAnimation()
        {
            //! 展示
            DoubleAnimation da = new DoubleAnimation();
            da.From = null;
            da.To = 100;
            da.Duration = new Duration(TimeSpan.FromSeconds(0.5));
            HideMenu.RenderTransform = new TranslateTransform();
            mStoryboard0 = new Storyboard();
            mStoryboard0.Children.Add(da);
            Storyboard.SetTarget(da, HideMenu);
            Storyboard.SetTargetProperty(da, new PropertyPath("RenderTransform.X"));

            //!隐藏
            DoubleAnimation doa = new DoubleAnimation();
            doa.From = null;
            doa.To = 0;
            doa.Duration = new Duration(TimeSpan.FromSeconds(0.5));
            mStoryboard1 = new Storyboard();
            mStoryboard1.Children.Add(doa);
            Storyboard.SetTarget(doa, HideMenu);
            Storyboard.SetTargetProperty(doa, new PropertyPath("RenderTransform.X"));
        }

        private void HideMenu_MouseEnter(object sender, MouseEventArgs e)
        {
            if (!isShowedMenu)
            {
                mStoryboard0.Begin(this);
                isShowedMenu = true;
                BtnBo.Visibility = Visibility.Collapsed;
            }
            
        }
        
        private void HideMenu_MouseLeave(object sender, MouseEventArgs e)
        {
            if (isShowedMenu)
            {
                mStoryboard1.Begin(this);
                isShowedMenu = false;
                BtnBo.Visibility = Visibility.Visible;
            }
        }
ViewModel.cs
public class AffineViewModel : ObservableObject
    {
        private ObservableCollection<ImageModel> _imageModels;
        public ObservableCollection<ImageModel> ImageList
        {
            get => _imageModels;
            set
            {
                if (value.Count > 10)
                {
                    value.RemoveAt(0);
                }
                SetProperty(ref _imageModels, value);
            }
        }

        private ImageModel _imageSelected;
        public ImageModel ImageSelected
        {
            get => _imageSelected;
            set
            {
                if (_imageSelected != value)
                {
                    if (value != null)
                    {
                        UpdateImage(value.Image);
                    }
                }
                SetProperty(ref _imageSelected, value);
            }
        }

        private BitmapSource _imageSource;
        public BitmapSource ImageSource
        {
            get => _imageSource;
            set
            {
                SetProperty(ref _imageSource, value);
            }
        }

        private string _logContent;
        public string LogContent
        {
            get => _logContent;
            set
            {
                SetProperty(ref _logContent, value);
            }
        }

        private Mat _srcImage;
        public Mat SrcImage
        {
            get => _srcImage;
            set
            {
                SetProperty(ref _srcImage, value);
            }
        }

        private int _imageIndex;
        public int ImageIndex
        {
            get => _imageIndex;
            set
            {
                SetProperty(ref _imageIndex, value);
            }
        }

        private int _vertical;
        public int Vertical
        {
            get => _vertical;
            set
            {
                SetProperty(ref _vertical, value);
            }
        }

        private int _horizontal;
        public int Horizontal
        {
            get => _horizontal;
            set
            {
                SetProperty(ref _horizontal, value);
            }
        }

        private int _angle;
        public int Angle
        {
            get => _angle;
            set
            {
                SetProperty(ref _angle, value);
            }
        }

        private int _bigTimes;
        public int BigTimes
        {
            get => _bigTimes;
            set
            {
                SetProperty(ref _bigTimes, value);
            }
        }

        private int _smalleTimes;
        public int SmalleTimes
        {
            get => _smalleTimes;
            set
            {
                SetProperty(ref _smalleTimes, value);
            }
        }

        public IRelayCommand ClearImageCommand { get; set; }
        public IRelayCommand LoadImageCommand { get; set; }
        public IRelayCommand TranslationCommand { get; set; }
        public IRelayCommand RotateCommand { get; set; }
        public IRelayCommand BiggerCommand { get; set; }
        public IRelayCommand SmallerCommand { get; set; }

        public AffineViewModel()
        {
            ClearImageCommand = new RelayCommand(ClearImage);
            LoadImageCommand = new RelayCommand(LoadImage);
            TranslationCommand = new RelayCommand(Translation);
            RotateCommand = new RelayCommand(Rotate);
            BiggerCommand = new RelayCommand(Bigger);
            SmallerCommand = new RelayCommand(Smaller);

            ImageList = new ObservableCollection<ImageModel>();

            Reecord("仿射变换");
        }

        private void Smaller()
        {
            if (SrcImage != null)
            {
                if (SmalleTimes != 0)
                {
                    OpenCvSharp.Point center = new OpenCvSharp.Point(SrcImage.Cols / 2, SrcImage.Rows / 2);
                    float angle = 0;
                    float scale = 1.0f / SmalleTimes;
                    Mat rot_mat = Cv2.GetRotationMatrix2D(center, angle, scale);
                    Mat warp_rotate_dst = Mat.Zeros(SrcImage.Rows, SrcImage.Cols, SrcImage.Type());
                    Cv2.WarpAffine(SrcImage, warp_rotate_dst, rot_mat, warp_rotate_dst.Size());

                    var hBitmap = warp_rotate_dst.ToBitmap().GetHbitmap();
                    var bitmapSource = Imaging.CreateBitmapSourceFromHBitmap(
                                        hBitmap, IntPtr.Zero, Int32Rect.Empty,
                                        BitmapSizeOptions.FromEmptyOptions());

                    ImageModel model = new ImageModel()
                    {
                        Image = bitmapSource,
                        Tag = "仿射变换_缩小"
                    };
                    ImageList.Add(model);
                    ImageSource = bitmapSource;
                    ImageIndex = ImageList.Count - 1;

                    GDIHelper.DeleteObject(hBitmap);

                    SrcImage = warp_rotate_dst;
                    Reecord("仿射变换_缩小");
                }
            }
        }

        private void Bigger()
        {
            if (SrcImage != null)
            {
                if (BigTimes != 0)
                {
                    OpenCvSharp.Point center = new OpenCvSharp.Point(SrcImage.Cols / 2, SrcImage.Rows / 2);
                    float angle = 0;
                    float scale = BigTimes;
                    Mat rot_mat = Cv2.GetRotationMatrix2D(center, angle, scale);
                    Mat warp_rotate_dst = Mat.Zeros(SrcImage.Rows, SrcImage.Cols, SrcImage.Type());

                    double new_height = SrcImage.Rows * scale;
                    double new_width = SrcImage.Cols * scale;
                    rot_mat.At<double>(0, 2) += (new_width - SrcImage.Cols) / 2;
                    rot_mat.At<double>(1, 2) += (new_height - SrcImage.Rows) / 2;
                    OpenCvSharp.Rect bbox = new RotatedRect(new Point2f(SrcImage.Cols / 2 * scale, SrcImage.Rows / 2 * scale), new Size2f(SrcImage.Cols * scale, SrcImage.Rows * scale), angle).BoundingRect();
                    Cv2.WarpAffine(SrcImage, warp_rotate_dst, rot_mat, bbox.Size);

                    var hBitmap = warp_rotate_dst.ToBitmap().GetHbitmap();
                    var bitmapSource = Imaging.CreateBitmapSourceFromHBitmap(
                                        hBitmap, IntPtr.Zero, Int32Rect.Empty,
                                        BitmapSizeOptions.FromEmptyOptions());

                    ImageModel model = new ImageModel()
                    {
                        Image = bitmapSource,
                        Tag = "仿射变换_放大"
                    };
                    ImageList.Add(model);
                    ImageSource = bitmapSource;
                    ImageIndex = ImageList.Count - 1;

                    GDIHelper.DeleteObject(hBitmap);

                    SrcImage = warp_rotate_dst;
                    Reecord("仿射变换_放大");
                }
            }
        }

        private void Rotate()
        {
            if (SrcImage != null)
            {
                OpenCvSharp.Point center = new OpenCvSharp.Point(SrcImage.Cols / 2, SrcImage.Rows / 2);
                float angle = 0.0f - Angle;
                float scale = 1.0f;
                Mat rot_mat = Cv2.GetRotationMatrix2D(center, angle, scale);
                Mat warp_rotate_dst = Mat.Zeros(SrcImage.Rows, SrcImage.Cols, SrcImage.Type());
                //Cv2.WarpAffine(SrcImage, warp_rotate_dst, rot_mat, warp_rotate_dst.Size());
                double sin_angle = Math.Sin(Math.Abs(angle) * Math.PI / 180);
                double cos_angle = Math.Cos(Math.Abs(angle) * Math.PI / 180);
                double new_height = SrcImage.Cols * sin_angle + SrcImage.Rows * cos_angle;
                double new_width = SrcImage.Cols * cos_angle + SrcImage.Rows * sin_angle;
                rot_mat.At<double>(0, 2) += (new_width - SrcImage.Cols) / 2;
                rot_mat.At<double>(1, 2) += (new_height - SrcImage.Rows) / 2;

                OpenCvSharp.Rect bbox = new RotatedRect(new Point2f(SrcImage.Cols / 2, SrcImage.Rows / 2), new Size2f(SrcImage.Cols, SrcImage.Rows), angle).BoundingRect();
                Cv2.WarpAffine(SrcImage, warp_rotate_dst, rot_mat, bbox.Size);

                var hBitmap = warp_rotate_dst.ToBitmap().GetHbitmap();
                var bitmapSource = Imaging.CreateBitmapSourceFromHBitmap(
                                    hBitmap, IntPtr.Zero, Int32Rect.Empty,
                                    BitmapSizeOptions.FromEmptyOptions());

                ImageModel model = new ImageModel()
                {
                    Image = bitmapSource,
                    Tag = "仿射变换_旋转"
                };
                ImageList.Add(model);
                ImageSource = bitmapSource;
                ImageIndex = ImageList.Count - 1;

                GDIHelper.DeleteObject(hBitmap);

                SrcImage = warp_rotate_dst;
                Reecord("仿射变换_旋转");
            }
        }

        private void Translation()
        {
            if (SrcImage != null)
            {
                Point2f[] srcTri = new Point2f[3];
                srcTri[0] = new Point2f(0.0f, 0.0f);
                srcTri[1] = new Point2f(SrcImage.Cols - 1.0f, 0.0f);
                srcTri[2] = new Point2f(0.0f, SrcImage.Rows - 1.0f);
                Point2f[] dstTri = new Point2f[3];
                dstTri[0] = new Point2f(Horizontal, Vertical);
                dstTri[1] = new Point2f(SrcImage.Cols - 1.0f + Horizontal, Vertical);
                dstTri[2] = new Point2f(Horizontal, SrcImage.Rows - 1.0f + Vertical);

                Mat warp_mat = Cv2.GetAffineTransform(srcTri, dstTri);
                Mat warp_dst = Mat.Zeros(SrcImage.Rows + Vertical, SrcImage.Cols + Horizontal, SrcImage.Type());

                Cv2.WarpAffine(SrcImage, warp_dst, warp_mat, warp_dst.Size());

                var hBitmap = warp_dst.ToBitmap().GetHbitmap();
                var bitmapSource = Imaging.CreateBitmapSourceFromHBitmap(
                                    hBitmap, IntPtr.Zero, Int32Rect.Empty,
                                    BitmapSizeOptions.FromEmptyOptions());

                ImageModel model = new ImageModel()
                {
                    Image = bitmapSource,
                    Tag = "仿射变换_平移"
                };
                ImageList.Add(model);
                ImageSource = bitmapSource;
                ImageIndex = ImageList.Count - 1;

                GDIHelper.DeleteObject(hBitmap);

                SrcImage = warp_dst;
                Reecord("仿射变换_平移");
            }
        }

        private void LoadImage()
        {
            OpenFileDialog file = new OpenFileDialog();
            file.ShowDialog();
            if (file.FileName != null && file.FileName != "")
            {
                BitmapImage bi = new BitmapImage();
                bi.BeginInit();
                bi.UriSource = new Uri(file.FileName, UriKind.Absolute);
                bi.EndInit();

                ImageModel model = new ImageModel()
                {
                    Image = bi,
                    Tag = "原始图像"
                };
                ImageList.Add(model);
                Reecord("加载图像");
                //SrcImage = new Mat(file.FileName, ImreadModes.AnyColor);
            }
        }

        private void ClearImage()
        {
            if (ImageList != null || ImageList.Count > 0)
            {
                ImageList.Clear();
                ImageSource = null;
            }
        }

        private void UpdateImage(BitmapSource source)
        {
            ImageSource = source;
            Bitmap bitmap;
            using (System.IO.MemoryStream ms = new System.IO.MemoryStream())
            {
                BitmapEncoder encoder = new BmpBitmapEncoder();
                encoder.Frames.Add(BitmapFrame.Create(source));
                encoder.Save(ms);
                bitmap = new Bitmap(ms);
            }
            SrcImage = BitmapConverter.ToMat(bitmap);
        }

        private void Reecord(string content)
        {
            string log = DateTime.Now.ToString("hh:mm:ff") + "\t" + content + "\n";
            LogContent += log;
        }
    }

写在结尾

这篇文章,作为实战分享文章,希望能够帮助到正在写WPF的朋友么,如果有什么问题也可以留言或者私信我

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值