WPF 自定义控件 CropingImage 防QQ头像 编辑功能
2015-07-24 22:10
417 查看
<ControlTemplate x:Key="reSizeThumb" TargetType="{x:Type Thumb}"> <Border Background="{DynamicResource BlueBrush}"> </Border> </ControlTemplate> <ControlTemplate x:Key="moveThumb" TargetType="{x:Type Thumb}"> <Grid x:Name="bg"> <Grid.Background> <RadialGradientBrush> <GradientStop Color="#00000000" Offset="1"/> <GradientStop Color="#50000000" Offset="1"/> </RadialGradientBrush> </Grid.Background> </Grid> </ControlTemplate> <Style TargetType="{x:Type local:CropingImgEx}"> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="{x:Type local:CropingImgEx}"> <Border Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}"> <Grid> <Image x:Name="imgSource" Source="{TemplateBinding Source}" Stretch="Uniform"/> <Canvas x:Name="canvas"> <Rectangle x:Name="topRec" Fill="{TemplateBinding MarkColor}" Canvas.Top="0" Width="{TemplateBinding Width}"/> <Rectangle x:Name="leftRec" Fill="{TemplateBinding MarkColor}" Canvas.Left="0"/> <Rectangle x:Name="bottomRec" Fill="{TemplateBinding MarkColor}" Canvas.Bottom="0" Width="{TemplateBinding Width}"/> <Rectangle x:Name="rightRec" Fill="{TemplateBinding MarkColor}" Canvas.Right="0"/> <Border x:Name="drogBorder" Width="{TemplateBinding DragControlLength}" Height="{TemplateBinding DragControlLength}"> <Grid UseLayoutRounding="True" SnapsToDevicePixels="True" Cursor="SizeAll" > <Grid.Background> <RadialGradientBrush> <GradientStop Color="#00000000" Offset="1"/> <GradientStop Color="#00000000" Offset="1"/> </RadialGradientBrush> </Grid.Background> <Ellipse Stroke="{DynamicResource BlueBrush}" StrokeThickness="1" StrokeDashArray="4,4" /> <Thumb x:Name="moveThumb" Width="{TemplateBinding DragControlLength}" Height="{TemplateBinding DragControlLength}" Template="{StaticResource moveThumb}"/> <Thumb Height="5" Width="5" x:Name="thumbTopLeft" Margin="-5" Template="{StaticResource reSizeThumb}" HorizontalAlignment="Left" VerticalAlignment="Top" Cursor="SizeNWSE"/> <Thumb Height="5" Width="5" x:Name="thumbTopRight" Margin="-5" Template="{StaticResource reSizeThumb}" HorizontalAlignment="Right" VerticalAlignment="Top" Cursor="SizeNESW"/> <Thumb Height="5" Width="5" x:Name="thumbBottomLeft" Margin="-5" Template="{StaticResource reSizeThumb}" HorizontalAlignment="Left" VerticalAlignment="Bottom" Cursor="SizeNESW"/> <Thumb Height="5" Width="5" x:Name="thumbBottomRight" Margin="-5" Template="{StaticResource reSizeThumb}" HorizontalAlignment="Right" VerticalAlignment="Bottom" Cursor="SizeNWSE"/> </Grid> </Border> </Canvas> </Grid> </Border> </ControlTemplate> </Setter.Value> </Setter> </Style>
上面是 CropingImgEx 的默认样式 里面的5个Thumb主要用于拖动和装饰拖动的边框, 直接使用CropingSource 来获取BitmapSource 代码写的 比较渣 后期有待优化 附一张效果图
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); } }
相关文章推荐
- Linux Rootkit之三:系统调用劫持简介
- 基于Linux的智能家居的设计(2)
- shell脚本:shell的基本元素-3 简单的echo输出
- linux at91看门狗驱动设置
- tomcat中使用Quartz造成内存泄露的问题解决
- centos6.6下安装GreenPlum4.3.5.2
- 在64位操作系统上使用FlashDevelop的Debug功能
- 基于Linux的智能家居的设计(1)
- linux配置java环境变量(详细)
- Django搭建简单的网站
- 3.1 linux进程 2015/7/22
- 定时访问网站
- dd if=/dev/zero of=的含义是什么?Linux 下的dd命令使用详解
- 关于shell排序
- Open vSwitch概述
- Apache本地可以显示外网不可以
- [转载]大型网站架构演变过程
- [转载]大型网站架构演变和知识体系
- Openssl s_time命令
- [转载]从100PV到1亿级PV网站架构演变