WPF 自定义控件 CropingImage 防QQ头像 编辑功能

 1 <ControlTemplate x:Key="reSizeThumb" TargetType="{x:Type Thumb}">

 2         <Border Background="{DynamicResource BlueBrush}">

 3         </Border>

 4     </ControlTemplate>

 5 

 6     <ControlTemplate x:Key="moveThumb" TargetType="{x:Type Thumb}">

 7         <Grid x:Name="bg">

 8             <Grid.Background>

 9                 <RadialGradientBrush>

10                     <GradientStop Color="#00000000" Offset="1"/>

11                     <GradientStop Color="#50000000" Offset="1"/>

12                 </RadialGradientBrush>

13             </Grid.Background>

14         </Grid>

15     </ControlTemplate>

16 

17     <Style TargetType="{x:Type local:CropingImgEx}">

18         <Setter Property="Template">

19             <Setter.Value>

20                 <ControlTemplate TargetType="{x:Type local:CropingImgEx}">

21                     <Border Background="{TemplateBinding Background}"

22                             BorderBrush="{TemplateBinding BorderBrush}"

23                             BorderThickness="{TemplateBinding BorderThickness}">

24                         <Grid>

25                             <Image x:Name="imgSource" Source="{TemplateBinding Source}" Stretch="Uniform"/>

26                             <Canvas x:Name="canvas">

27 

28                                 <Rectangle x:Name="topRec" Fill="{TemplateBinding MarkColor}"  Canvas.Top="0" Width="{TemplateBinding Width}"/>

29                                 <Rectangle x:Name="leftRec" Fill="{TemplateBinding MarkColor}" Canvas.Left="0"/>

30                                 <Rectangle x:Name="bottomRec" Fill="{TemplateBinding MarkColor}" Canvas.Bottom="0" Width="{TemplateBinding Width}"/>

31                                 <Rectangle x:Name="rightRec" Fill="{TemplateBinding MarkColor}" Canvas.Right="0"/>

32                                 <Border x:Name="drogBorder"

33                                         Width="{TemplateBinding DragControlLength}" Height="{TemplateBinding DragControlLength}">

34                                     <Grid UseLayoutRounding="True" SnapsToDevicePixels="True" Cursor="SizeAll" >

35                                         <Grid.Background>

36                                             <RadialGradientBrush>

37                                                 <GradientStop Color="#00000000" Offset="1"/>

38                                                 <GradientStop Color="#00000000" Offset="1"/>

39                                             </RadialGradientBrush>

40                                         </Grid.Background>

41                                         <Ellipse  Stroke="{DynamicResource BlueBrush}" StrokeThickness="1" StrokeDashArray="4,4" />

42                                         <Thumb x:Name="moveThumb" Width="{TemplateBinding DragControlLength}" Height="{TemplateBinding DragControlLength}"  Template="{StaticResource moveThumb}"/>

43                                         <Thumb Height="5" Width="5" x:Name="thumbTopLeft" Margin="-5" Template="{StaticResource reSizeThumb}"  HorizontalAlignment="Left" VerticalAlignment="Top" Cursor="SizeNWSE"/>

44                                         <Thumb Height="5" Width="5" x:Name="thumbTopRight"  Margin="-5" Template="{StaticResource reSizeThumb}"  HorizontalAlignment="Right" VerticalAlignment="Top" Cursor="SizeNESW"/>

45                                         <Thumb Height="5" Width="5" x:Name="thumbBottomLeft"  Margin="-5" Template="{StaticResource reSizeThumb}"  HorizontalAlignment="Left" VerticalAlignment="Bottom" Cursor="SizeNESW"/>

46                                         <Thumb Height="5" Width="5" x:Name="thumbBottomRight"  Margin="-5" Template="{StaticResource reSizeThumb}" HorizontalAlignment="Right" VerticalAlignment="Bottom" Cursor="SizeNWSE"/>

47                                         

48                                         

49                                     </Grid>

50                                 </Border>

51                             </Canvas>

52 

53                         </Grid>

54                     </Border>

55                 </ControlTemplate>

56             </Setter.Value>

57         </Setter>

58     </Style>

上面是 CropingImgEx 的默认样式    里面的5个Thumb主要用于拖动和装饰拖动的边框, 直接使用CropingSource 来获取BitmapSource 代码写的 比较渣  后期有待优化   附一张效果图 

WPF 自定义控件 CropingImage 防QQ头像 编辑功能

 public class CropingImgEx : Control

    {

        static CropingImgEx()

        {

            DefaultStyleKeyProperty.OverrideMetadata(typeof(CropingImgEx), new FrameworkPropertyMetadata(typeof(CropingImgEx)));

            using (System.Drawing.Graphics graphics = System.Drawing.Graphics.FromHwnd(IntPtr.Zero))

            {

                s_dpiX = graphics.DpiX;

                s_dpiY = graphics.DpiY;

            }

        }





        public CropingImgEx()

        {

            this.Unloaded += CropingImgEx_Unloaded;

        }









        public double DragControlLength

        {

            get { return (double)GetValue(DragControlLengthProperty); }

            set { SetValue(DragControlLengthProperty, value); }

        }



        public static readonly DependencyProperty DragControlLengthProperty =

            DependencyProperty.Register("DragControlLength", typeof(double), typeof(CropingImgEx), new PropertyMetadata(null));







        public double MinControlLength

        {

            get { return (double)GetValue(MinControlLengthProperty); }

            set { SetValue(MinControlLengthProperty, value); }

        }



        // Using a DependencyProperty as the backing store for MinControlLength.  This enables animation, styling, binding, etc...

        public static readonly DependencyProperty MinControlLengthProperty =

            DependencyProperty.Register("MinControlLength", typeof(double), typeof(CropingImgEx), new PropertyMetadata(null));







        public Brush MarkColor

        {

            get { return (Brush)GetValue(MarkColorProperty); }

            set { SetValue(MarkColorProperty, value); }

        }



        // Using a DependencyProperty as the backing store for MarkColor.  This enables animation, styling, binding, etc...

        public static readonly DependencyProperty MarkColorProperty =

            DependencyProperty.Register("MarkColor", typeof(Brush), typeof(CropingImgEx), new PropertyMetadata(null));







        public BitmapSource CropingSource

        {

            get { return (BitmapSource)GetValue(CropingSourceProperty); }

            set { SetValue(CropingSourceProperty, value); }

        }



        // Using a DependencyProperty as the backing store for CropingSource.  This enables animation, styling, binding, etc...

        public static readonly DependencyProperty CropingSourceProperty =

            DependencyProperty.Register("CropingSource", typeof(BitmapSource), typeof(CropingImgEx), new PropertyMetadata(null));



        public BitmapSource Source

        {

            get { return (BitmapSource)GetValue(SourceProperty); }

            set { SetValue(SourceProperty, value); }



        }



        public static readonly DependencyProperty SourceProperty =

            DependencyProperty.Register("Source", typeof(BitmapSource), typeof(CropingImgEx), new PropertyMetadata(new PropertyChangedCallback(

                OnSourceChanged)));



        public static void OnSourceChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)

        {

            CropingImgEx img = sender as CropingImgEx;

            if (e.NewValue != null)

            {

                BitmapSource source = e.NewValue as BitmapSource;



                if (img.imgSource != null)

                {

                    Size targetSize = img.Preview(source.PixelWidth, source.PixelHeight, 300, 300);



                    img.Width = targetSize.Width;

                    img.Height = targetSize.Height;



                    img.DragControlLength = Math.Min(targetSize.Width, targetSize.Height);

                    Canvas.SetTop(img.dragBorder, 0);

                    Canvas.SetLeft(img.dragBorder, 0);

                    img.SetMark(0, 0);

                    img.SetCropingSource();

                }

            }

        }



        Size Preview(double sourceWidht,double sourceHeight, double maxWidth, double maxHeight)

        {



            scaleX = maxWidth / sourceWidht;

            scaleY = maxHeight / sourceHeight;



            Size result;

            if (scaleX < scaleY)

            {

                result = new Size(maxWidth, (int)(sourceHeight * scaleX));

            }

            else if (scaleX > scaleY)

            {

                result = new Size((int)(sourceWidht * scaleY), maxHeight);

            }

            else

            {

                result = new Size(maxWidth, maxHeight);

            }

            return result;

        }









        private Thumb moveThumb;

        private Thumb thumbTopLeft;

        private Thumb thumbTopRight;

        private Thumb thumbBottomLeft;

        private Thumb thumbBottomRight;

        private FrameworkElement dragBorder;



        private Rectangle markTop;

        private Rectangle markLeft;

        private Rectangle markRight;

        private Rectangle markBottom;



        private Image imgSource;



        public override void OnApplyTemplate()

        {

            base.OnApplyTemplate();

            moveThumb = GetTemplateChild("moveThumb") as Thumb;



            thumbTopLeft = GetTemplateChild("thumbTopLeft") as Thumb;

            thumbTopRight = GetTemplateChild("thumbTopRight") as Thumb;

            thumbBottomLeft = GetTemplateChild("thumbBottomLeft") as Thumb;

            thumbBottomRight = GetTemplateChild("thumbBottomRight") as Thumb;

            dragBorder = GetTemplateChild("drogBorder") as FrameworkElement;



            markTop = GetTemplateChild("topRec") as Rectangle;

            markLeft = GetTemplateChild("leftRec") as Rectangle;

            markRight = GetTemplateChild("rightRec") as Rectangle;

            markBottom = GetTemplateChild("bottomRec") as Rectangle;



            imgSource = GetTemplateChild("imgSource") as Image;

            Canvas.SetTop(dragBorder, (Width - DragControlLength) / 2);

            Canvas.SetLeft(dragBorder, (Height - DragControlLength) / 2);



            moveThumb.DragDelta += moveThumb_DragDelta;



            thumbTopLeft.DragDelta += thumbTopLeft_DragDelta;

            thumbTopRight.DragDelta += thumbTopRight_DragDelta;

            thumbBottomLeft.DragDelta += thumbBottomLeft_DragDelta;

            thumbBottomRight.DragDelta += thumbBottomRight_DragDelta;



            thumbTopLeft.DragCompleted += thumbBottomLeft_DragCompleted;

            thumbTopRight.DragCompleted += thumbBottomLeft_DragCompleted;

            thumbBottomLeft.DragCompleted += thumbBottomLeft_DragCompleted;

            thumbBottomRight.DragCompleted += thumbBottomLeft_DragCompleted;



            SetCropingSource();

            SetMark((Width - DragControlLength) / 2, (Height - DragControlLength) / 2);

        }



        void CropingImgEx_Unloaded(object sender, RoutedEventArgs e)

        {

            moveThumb.DragDelta -= moveThumb_DragDelta;

            thumbTopLeft.DragDelta -= thumbTopLeft_DragDelta;

            thumbTopRight.DragDelta -= thumbTopRight_DragDelta;

            thumbBottomLeft.DragDelta -= thumbBottomLeft_DragDelta;

            thumbBottomRight.DragDelta -= thumbBottomRight_DragDelta;



            thumbBottomLeft.DragCompleted -= thumbBottomLeft_DragCompleted;

            thumbTopRight.DragCompleted -= thumbBottomLeft_DragCompleted;

            thumbBottomLeft.DragCompleted -= thumbBottomLeft_DragCompleted;

            thumbBottomRight.DragCompleted -= thumbBottomLeft_DragCompleted;

        }







        void thumbBottomLeft_DragCompleted(object sender, DragCompletedEventArgs e)

        {

            SetCropingSource();

        }







        void thumbBottomRight_DragDelta(object sender, DragDeltaEventArgs e)

        {



            if (e.HorizontalChange == 0)

            {

                return;

            }

            double width = DragControlLength + e.HorizontalChange;



            double top = Canvas.GetTop(dragBorder);



            double left = Canvas.GetLeft(dragBorder);

            Console.WriteLine("Resize Left:" + Canvas.GetLeft(dragBorder) + "\tResize Top:" + Canvas.GetTop(dragBorder));

            if (left + width > Width || width + top > Height || width <= MinControlLength)

            {

                return;

            }



            DragControlLength = width;

            SetMark(top, left);

            e.Handled = true;

        }



        void thumbBottomLeft_DragDelta(object sender, DragDeltaEventArgs e)

        {



            if (e.HorizontalChange == 0)

            {

                return;

            }



            double width = DragControlLength - e.HorizontalChange;



            double left = Canvas.GetLeft(dragBorder) + e.HorizontalChange;



            double top = Canvas.GetTop(dragBorder);

            Console.WriteLine("Resize Left:" + Canvas.GetLeft(dragBorder) + "\tResize Top:" + Canvas.GetTop(dragBorder));

            if (left < 0 || width <= MinControlLength || top + width > Height)

            {

                return;

            }



            Canvas.SetLeft(dragBorder, left);



            DragControlLength = width;

            SetMark(top, left);

            e.Handled = true;

        }



        void thumbTopRight_DragDelta(object sender, DragDeltaEventArgs e)

        {



            if (e.HorizontalChange == 0)

            {

                return;

            }

            double width = DragControlLength + e.HorizontalChange;



            double top = Canvas.GetTop(dragBorder) - e.HorizontalChange;



            double left = Canvas.GetLeft(dragBorder);

            Console.WriteLine("Resize Left:" + Canvas.GetLeft(dragBorder) + "\tResize Top:" + Canvas.GetTop(dragBorder));

            if (top < 0 || left + width >= Width || width < MinControlLength)

            {

                return;

            }



            Canvas.SetTop(dragBorder, top);



            DragControlLength = width;

            SetMark(top, left);

            e.Handled = true;

        }



        void thumbTopLeft_DragDelta(object sender, DragDeltaEventArgs e)

        {

            if (e.HorizontalChange == 0)

            {

                return;

            }



            double width = DragControlLength - e.HorizontalChange;



            double top = Canvas.GetTop(dragBorder) + e.HorizontalChange;



            double left = Canvas.GetLeft(dragBorder) + e.HorizontalChange;



            Console.WriteLine("Resize Left:" + Canvas.GetLeft(dragBorder) + "\tResize Top:" + Canvas.GetTop(dragBorder));

            if (top < 0 || width <= MinControlLength || left < 0)

            {

                return;

            }



            Canvas.SetTop(dragBorder, top);



            Canvas.SetLeft(dragBorder, left);



            DragControlLength = width;

            SetMark(top, left);

            e.Handled = true;

        }



        void moveThumb_DragDelta(object sender, DragDeltaEventArgs e)

        {

            double top = Canvas.GetTop(dragBorder) + e.VerticalChange;

            double left = Canvas.GetLeft(dragBorder) + e.HorizontalChange;

            if (top <= 0)

                top = 0;

            if (top >= (Height - DragControlLength))

                top = Height - DragControlLength;

            if (left <= 0)

                left = 0;

            if (left >= (Width - DragControlLength))

                left = Width - DragControlLength;

            Canvas.SetTop(dragBorder, nTop);

            Canvas.SetLeft(dragBorder, nLeft);

            SetCropingSource();

            SetMark(nTop, nLeft);

            Console.WriteLine("Move Left:" + Canvas.GetLeft(dragBorder) + "\tMove Top:" + Canvas.GetTop(dragBorder));

        }



        private static float s_dpiX;

        private static float s_dpiY;

        private double scaleX; // 缩放比例

        private double scaleY; // 





        private Point UnitsToPx(double x, double y)

        {

            scaleX = Source.PixelWidth / this.Width;

            scaleY = Source.PixelHeight / this.Height;

            return new Point((int)(x * s_dpiX / 96), (int)(y * s_dpiY / 96));

        }



        private void SetCropingSource()

        {

            Point point = UnitsToPx(Canvas.GetLeft(dragBorder), Canvas.GetTop(dragBorder));



            int left = (int)(point.X * scaleX);

            int top = (int)(point.Y * scaleY);



            int width = (int)(dragBorder.Width * scaleX);

            int height = (int)(dragBorder.Height * scaleY);

            Int32Rect rect = new Int32Rect(left, top, width, height);



            CroppedBitmap bitImage = new CroppedBitmap(Source, rect);

            CropingSource = bitImage;



        }



        private void SetMark(double top, double left)

        {

            markTop.Height = top;

            double height = Height - top - DragControlLength;

            if (height < 0)

            {

                height = 0;

            }

            markBottom.Height = height;

            markLeft.Width = left;

            markLeft.Height = DragControlLength;

            Canvas.SetTop(markLeft, top);

            markRight.Width = Width - left - DragControlLength;

            markRight.Height = DragControlLength;

            Canvas.SetTop(markRight, top);

        }

    }

 

你可能感兴趣的:(image)