wpf Canvas 绘制矩形 显示移动轨迹

cs文件

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;

namespace Measure
{
    enum PosMode{
        Show,
        Move,
        Delete,
        Zoom
    }

    /// <summary>
    /// OneImagePanel.xaml 的交互逻辑
    /// </summary>
    public partial class OneImagePanel : UserControl
    {
        public static void SaveBitmapImageAsJpeg(BitmapSource image, string imageFileName)
        {
            //已知BitmapImage image

            JpegBitmapEncoder encoder = new JpegBitmapEncoder();
            encoder.QualityLevel = 100;

            encoder.Frames.Add(BitmapFrame.Create(image));

            FileStream fileStream = new FileStream(imageFileName, FileMode.Create, FileAccess.ReadWrite);

            encoder.Save(fileStream);

            fileStream.Close();
        }

        public OneImagePanel()
        {
            InitializeComponent();
        }
        private double scale = 0;
        public void SetImage(BitmapSource bitmapSource)
        {
            cameraImage.Source = bitmapSource;
            if(scale==0)
            {
                double scaleX = _Canvas.Width / bitmapSource.Width;
                double scaleY = _Canvas.Height / bitmapSource.Height;
                scale = scaleX > scaleY ? scaleY : scaleX;
                _Scale.ScaleX = scale;
                _Scale.ScaleY = scale;
            }
        }
              
        System.Windows.Point BackcenterPoint;
        private void Back_img_MouseWheel(object sender, MouseWheelEventArgs e)
        {
            BackcenterPoint = e.GetPosition(_Canvas);
            System.Windows.Point pt1 = _Canvas.RenderTransform.Inverse.Transform(BackcenterPoint);
            _Translate.X = (BackcenterPoint.X - pt1.X) * this._Scale.ScaleX;
            _Translate.Y = (BackcenterPoint.Y - pt1.Y) * this._Scale.ScaleY;
            this._Scale.CenterX = BackcenterPoint.X;
            this._Scale.CenterY = BackcenterPoint.Y;
            if ((_Scale.ScaleX + (double)e.Delta / 2400) >= 0.1 && (_Scale.ScaleX + (double)e.Delta / 2400) < 2)
            {
                _Scale.ScaleX += (double)e.Delta / 2400;
                _Scale.ScaleY += (double)e.Delta / 2400;
            }
        }
        private bool mouseLDown = false;
        private bool mouseRDown = false;
        private System.Windows.Point mouseXY;
        private bool selectMove = false;
        private bool ZoomMove = false;
        private double RectMinSize = 30;
        //当前选中的矩形
        System.Windows.Shapes.Rectangle currnetRectang = null;
        private void canvas_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            var img = sender as Canvas;
            if (img == null)
            {
                return;
            }            
            img.CaptureMouse();
            mouseXY = e.GetPosition(img);
            selectMove = false;
            PosMode mode = SelectRect(e.GetPosition(img));
            if (mode != PosMode.Show)
            {
                if (e.ClickCount > 1)
                {
                    //双击矩形处理
                    return;
                }
                double x = Canvas.GetLeft(currnetRectang);
                double y = Canvas.GetTop(currnetRectang);

                if (mode == PosMode.Zoom)
                    ZoomMove = true;
                else
                {                  
                    selectMove = true;
                }

              
                DeleteLabel.Visibility = Visibility.Visible;
                Canvas.SetLeft(DeleteLabel, x - 32);
                Canvas.SetTop(DeleteLabel, y - 32);

                ZoomLabel.Visibility = Visibility.Visible;
                Canvas.SetLeft(ZoomLabel, x + currnetRectang.Width);
                Canvas.SetTop(ZoomLabel, y + currnetRectang.Height);
                
                return;
            }
            DeleteLabel.Visibility = Visibility.Collapsed;
            ZoomLabel.Visibility = Visibility.Collapsed;
           
            mouseLDown = true;

            TempRect.Width = 0;TempRect.Height = 0;
            TempRect.Visibility = Visibility.Visible;
        }
               
        private void canvas_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
        {
            var img = sender as Canvas;
            if (img == null)
            {
                return;
            }
            Point CurPos = e.GetPosition(img);
            img.ReleaseMouseCapture();
            selectMove = false;
            ZoomMove = false;
            if (mouseLDown)
            {
                Rectangle rect = new Rectangle();
                rect.StrokeThickness = 2;
                rect.Stroke = new SolidColorBrush(Colors.Red);
                rect.Width = Math.Abs(mouseXY.X - CurPos.X);
                rect.Height = Math.Abs(mouseXY.Y - CurPos.Y);
                Canvas.SetLeft(rect, Math.Min(mouseXY.X, CurPos.X));
                Canvas.SetTop(rect, Math.Min(mouseXY.Y, CurPos.Y));
                if (rect.Width > RectMinSize && rect.Height > RectMinSize)
                {
                    //画完后记录
                    rect.Name = "DrawRect";
                    _Canvas.Children.Add(rect);
                }
            }
            mouseLDown = false;
            TempRect.Visibility = Visibility.Collapsed;
        }
        private void _Canvas_MouseRightButtonDown(object sender, MouseButtonEventArgs e)
        {
            var img = sender as Canvas;
            if (img == null)
            {
                return;
            }
            img.CaptureMouse();
            mouseRDown = true;
            mouseXY = e.GetPosition(img);
        }
        private void _Canvas_MouseRightButtonUp(object sender, MouseButtonEventArgs e)
        {
            var img = sender as Canvas;
            if (img == null)
            {
                return;
            }
            img.ReleaseMouseCapture();
            mouseRDown = false;
        }

       
        private void canvas_MouseMove(object sender, MouseEventArgs e)
        {
            var img = sender as Canvas;
            if (img == null)
            {
                return;
            }
            PosMode mode =  SelectRect(e.GetPosition(img));
            switch (mode)
            {
                case PosMode.Move:
                    this.Cursor = Cursors.Hand;break;
                case PosMode.Zoom:
                    this.Cursor = Cursors.SizeNWSE; break;
                default:
                    this.Cursor = Cursors.Arrow; break;
            }
            if (mouseRDown)
            {
                //右键移动视图
                Domousemove(img, e);
            }
            else if (ZoomMove)
            {
                ZoomSelectRectang(e.GetPosition(img));
            }
            else if (selectMove)
            {
                //左键移动矩形
                MoveSelectRectang(e.GetPosition(img));
            }
            else if (mouseLDown)
            {
                //左键画图
                DrawRect(e.GetPosition(img));
            }
            
        }
        private void Domousemove(Canvas img, MouseEventArgs e)
        {
            if (e.RightButton != MouseButtonState.Pressed)
            {
                return;
            }
            var position = e.GetPosition(img);
            _Translate.X += (position.X - mouseXY.X) * _Scale.ScaleX;
            _Translate.Y += (position.Y - mouseXY.Y) * _Scale.ScaleY;            
        }

        private void DrawRect(Point CurPos)
        {
            TempRect.Width = Math.Abs(mouseXY.X - CurPos.X);
            TempRect.Height = Math.Abs(mouseXY.Y - CurPos.Y);
            Canvas.SetLeft(TempRect, Math.Min(mouseXY.X, CurPos.X));
            Canvas.SetTop(TempRect, Math.Min(mouseXY.Y, CurPos.Y));
        }
        private void MoveSelectRectang(Point CurPos)
        {
            double offsetX = (CurPos.X - mouseXY.X);
            double offsetY = (CurPos.Y - mouseXY.Y);
            //if (offsetX > 1 || offsetY > 1)
            {
                mouseXY = CurPos;
                double x = Canvas.GetLeft(currnetRectang);
                double y = Canvas.GetTop(currnetRectang);
                Canvas.SetLeft(currnetRectang, (x + offsetX));
                Canvas.SetTop(currnetRectang, (y + offsetY));

                Canvas.SetLeft(DeleteLabel, x - 32);
                Canvas.SetTop(DeleteLabel, y - 32);

                Canvas.SetLeft(ZoomLabel, x + currnetRectang.Width);
                Canvas.SetTop(ZoomLabel, y + currnetRectang.Height);             
            }
        }
        private void ZoomSelectRectang(Point CurPos)
        {
            double offsetX = (CurPos.X - mouseXY.X);
            double offsetY = (CurPos.Y - mouseXY.Y);
            mouseXY = CurPos;
            double x = Canvas.GetLeft(currnetRectang);
            double y = Canvas.GetTop(currnetRectang);     
            if(currnetRectang.Width+offsetX>RectMinSize)
                currnetRectang.Width += offsetX;
            if (currnetRectang.Height + offsetY > RectMinSize)
                currnetRectang.Height += offsetY;
            currnetRectang.Width = currnetRectang.Width < RectMinSize ? RectMinSize : currnetRectang.Width;
            currnetRectang.Height = currnetRectang.Height < RectMinSize ? RectMinSize : currnetRectang.Height;

            Canvas.SetLeft(ZoomLabel, x + currnetRectang.Width);
            Canvas.SetTop(ZoomLabel, y + currnetRectang.Height);
        }
        //return 0-未选中 1-内部 2-左右边界 3-上下边界 4-角点
        static int rang = 20;
        private PosMode SelectRect(Point CurPos)
        {
            PosMode bfind = PosMode.Show;
            for (int i = _Canvas.Children.Count - 1; i > 0; i--)
            {
                UIElement uitem = _Canvas.Children[i];
                if (uitem.GetType() == typeof(Rectangle))
                {
                    Rectangle rect = _Canvas.Children[i] as Rectangle;
                    if (rect.Name == "DrawRect")
                    {
                        rect.Stroke = new SolidColorBrush(Colors.Red);
                        Rect roi = new Rect(Canvas.GetLeft(rect), Canvas.GetTop(rect), rect.Width, rect.Height);
                        if (roi.Contains(CurPos))
                        {
                            currnetRectang = rect;
                            rect.Stroke = new SolidColorBrush(Colors.Green);
                            bfind = PosMode.Move;
                            if ((CurPos.X > roi.Right - rang && CurPos.X < roi.Right + rang) &&
                                (CurPos.Y > roi.Bottom - rang && CurPos.Y < roi.Bottom + rang))
                            {
                                bfind = PosMode.Zoom;
                            }
                        }
                    }
                }
            }           
            return bfind;
        }

        private void DeleteLabel_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            //删除矩形
            _Canvas.Children.Remove(currnetRectang);               
            
        }

        private void btnZoomUp_Click(object sender, RoutedEventArgs e)
        {
            if (_Scale.ScaleX < 2 && _Scale.ScaleY < 2)
            {
                _Scale.ScaleX += 0.1;
                _Scale.ScaleY += 0.1;
            }
        }

        private void btnZoomDown_Click(object sender, RoutedEventArgs e)
        {
            if (_Scale.ScaleX > 0.2 && _Scale.ScaleY > 0.2)
            {
                _Scale.ScaleX -= 0.1;
                _Scale.ScaleY -= 0.1;
            }
        }

        private void btnZoomOrigin_Click(object sender, RoutedEventArgs e)
        {
            _Scale.ScaleX = scale;
            _Scale.ScaleY = scale;
            _Scale.CenterX = 0;
            _Scale.CenterY = 0;
            _Translate.X = 0;
            _Translate.Y = 0;
        }
      
        private void _Canvas_MouseLeave(object sender, MouseEventArgs e)
        {
            DeleteLabel.Visibility = Visibility.Collapsed;
            ZoomLabel.Visibility = Visibility.Collapsed;
        }
    }
}

 xmal文件

<UserControl x:Class="Measure.OneImagePanel"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
             mc:Ignorable="d">
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="*"></RowDefinition>
            <RowDefinition Height="50"></RowDefinition>
        </Grid.RowDefinitions>
        <Border  VerticalAlignment="Center" HorizontalAlignment="Center"  ClipToBounds="True" Grid.Row="0">
            <Canvas x:Name ="_Canvas" MouseLeftButtonDown="canvas_MouseLeftButtonDown" MouseLeftButtonUp="canvas_MouseLeftButtonUp" 
                   MouseRightButtonDown="_Canvas_MouseRightButtonDown" MouseRightButtonUp="_Canvas_MouseRightButtonUp"
                    MouseMove="canvas_MouseMove" Width="800" Height="800" MouseLeave="_Canvas_MouseLeave">
                <Canvas.RenderTransform>
                    <TransformGroup>
                        <ScaleTransform x:Name="_Scale"  ScaleX="1"  ScaleY="1"/>
                        <TranslateTransform x:Name="_Translate" X="0" Y="0"></TranslateTransform>
                    </TransformGroup>
                </Canvas.RenderTransform>
                <Image x:Name="cameraImage" Stretch="Uniform" HorizontalAlignment="Center" StretchDirection="Both"  MouseWheel="Back_img_MouseWheel" />
                <Rectangle x:Name="TempRect" Stroke="Red" StrokeThickness="2" Visibility="Collapsed"/>

                <Label x:Name="DeleteLabel"  Width="32" Height="32" Visibility="Collapsed" 
                       MouseLeftButtonDown="DeleteLabel_MouseLeftButtonDown"  >
                    <Label.Background>
                        <ImageBrush ImageSource="delete.png"/>
                    </Label.Background>
                </Label>
                <Label x:Name="ZoomLabel"  Width="32" Height="32" Visibility="Collapsed" >
                    <Label.Background>
                        <ImageBrush ImageSource="zoom.png"/>
                    </Label.Background>
                </Label>
            </Canvas>
        </Border>
        <StackPanel  Orientation="Horizontal"  VerticalAlignment="Center" HorizontalAlignment="Center"  ClipToBounds="True" Grid.Row="1">
            <Button Name="btnZoomDown"  Click="btnZoomDown_Click" Margin="10,0,10,0" Width="50"  Height="50" >
                <Button.Background>
                    <ImageBrush ImageSource="zoomDown.png"/>
                </Button.Background>
            </Button>
            <Button Name="btnZoomOrigin"  Click="btnZoomOrigin_Click" Margin="10,0,10,0" Width="50"  Height="50" >
                <Button.Background>
                    <ImageBrush ImageSource="zoomOrigin.png"/>
                </Button.Background>
            </Button>
            <Button Name="btnZoomUp"  Click="btnZoomUp_Click"  Margin="10,0,10,0" Width="50"  Height="50" >
                <Button.Background>
                    <ImageBrush ImageSource="zoomUp.png"/>
                </Button.Background>
            </Button>
        </StackPanel>
    </Grid>
</UserControl>

特别说明

  1. 绘图窗口为UserControl控件
  2. 设置图片使用  public void SetImage(BitmapSource bitmapSource);
  3. 有几张png文件,需外部导入 提取码:k6qpicon-default.png?t=L892https://pan.baidu.com/s/1T68xqRyqEYVf16CRaljfQg
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值