说废话,无卵用、代码可能有点乱
一、剪切器界面设计
<UserControl x:Class="DialogEx.Controls.ImageDealer"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300" Background="Transparent"
SnapsToDevicePixels="True"
PreviewMouseDown="UserControl_MouseDown" PreviewMouseUp="UserControl_MouseUp" MouseLeave="UserControl_MouseLeave" PreviewMouseMove="UserControl_MouseMove"
>
<Grid Name="MainGrid" MinHeight="200" MinWidth="200" >
<Image Name="SoureceImage" Stretch="Fill"></Image>
<Border Name="ImageArea" BorderBrush="Red" BorderThickness="1,1,1,1" Panel.ZIndex="5" Margin="50" Width="100" Height="100">
<Grid >
<Rectangle Name="R_LeftUp" Width="5" Height="5" Margin="-3" VerticalAlignment="Top" HorizontalAlignment="Left" Fill="White" Panel.ZIndex="0" Cursor="SizeNWSE"/>
<Rectangle Name="R_Up" Width="5" Height="5" Margin="-3" VerticalAlignment="Top" HorizontalAlignment="Center" Fill="White" Panel.ZIndex="0" Cursor="SizeNS"/>
<Rectangle Name="R_RightUp" Width="5" Height="5" Margin="-3" VerticalAlignment="Top" HorizontalAlignment="Right" Fill="White" Panel.ZIndex="0" Cursor="SizeNESW"/>
<Rectangle Name="R_Right" Width="5" Height="5" Margin="-3" VerticalAlignment="Center" HorizontalAlignment="Right" Fill="White" Panel.ZIndex="0" Cursor="SizeWE"/>
<Rectangle Name="R_RightDown" Width="5" Height="5" Margin="-3" VerticalAlignment="Bottom" HorizontalAlignment="Right" Fill="White" Panel.ZIndex="0" Cursor="SizeNWSE"/>
<Rectangle Name="R_Down" Width="5" Height="5" Margin="-3" VerticalAlignment="Bottom" HorizontalAlignment="Center" Fill="White" Panel.ZIndex="0" Cursor="SizeNS"/>
<Rectangle Name="R_LeftDown" Width="5" Height="5" Margin="-3" VerticalAlignment="Bottom" HorizontalAlignment="Left" Fill="White" Panel.ZIndex="0" Cursor="SizeNESW"/>
<Rectangle Name="R_Left" Width="5" Height="5" Margin="-3" VerticalAlignment="Center" HorizontalAlignment="Left" Fill="White" Panel.ZIndex="0" Cursor="SizeWE"/>
<!--<GridSplitter Height="5" Width="5" VerticalAlignment="Bottom" HorizontalAlignment="Stretch"></GridSplitter>-->
</Grid>
</Border>
</Grid>
</UserControl>
using DialogEx.Class;
using System;
using System.Collections.Generic;
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.Navigation;
using System.Windows.Shapes;
namespace DialogEx.Controls
{
public partial class ImageDealer : UserControl
{
#region 公共字段
public static readonly RoutedEvent OnCutImagingEventHandler = EventManager.RegisterRoutedEvent("OnCutImaging", RoutingStrategy.Bubble, typeof(RoutedEventHandler), typeof(ImageDealer));
public event RoutedEventHandler OnCutImaging
{
add { base.AddHandler(OnCutImagingEventHandler, value); }
remove { base.RemoveHandler(OnCutImagingEventHandler, value); }
}
private BitmapImage _BitSource;
public BitmapImage BitSource
{
get { return this._BitSource; }
set
{
this._BitSource = value;
this.SoureceImage.Source = value;
//CutImage();
}
}
#endregion
#region 依赖属性
/// <summary>
/// 边距
/// </summary>
public double MaxMargin = 2;
//public Brush BorderBrush;
#endregion
#region ==私有字段==
/// <summary>
/// 鼠标样式
/// </summary>
private Cursor MouseCursor = Cursors.Arrow;
/// <summary>
/// 鼠标位置
/// </summary>
private MouseLocationEnum MouseLocation = MouseLocationEnum.None;
/// <summary>
/// 鼠标行为
/// </summary>
private MouseActionEx Action { get; set; }
/// <summary>
/// 边框粗细
/// </summary>
private double BorderWidth = 1;
/// <summary>
/// 拖拽前鼠标按下位置
/// </summary>
private Point MouseDownPoint;
/// <summary>
/// 拖拽前控件位置
/// </summary>
private Point MouseDownLocate;
#endregion
#region ==方法==
public ImageDealer()
{
InitializeComponent();
}
/// <summary>
/// 计算区域圆点及宽高
/// </summary>
/// <param name="MouseButtonLocate">鼠标相对背景MainGrid位置</param>
/// <param name="IsRectangle">是否正方形</param>
/// <returns>NULL 或 具体值</returns>
private RectangleAreaModel CalculatedArea(Point MouseButtonLocate, bool IsRectangle)
{
Point Locate = this.ImageArea.TransformToAncestor((UIElement)this.MainGrid).Transform(new Point(0, 0));
//边框宽度
double BorderWidth = this.BorderWidth;
//整体宽度
double RectWidth = this.ImageArea.ActualWidth;
//整体高度
double RectHeight = this.ImageArea.ActualHeight;
//裁剪区域
Point OriginalPoint = new Point(0, 0);//圆点坐标
Point TheoryPoint = new Point(0, 0); //理论坐标
double TheoryWidth = 0; //理论宽度
double TheoryHeight = 0; //理论高度
switch (MouseLocation)
{
case MouseLocationEnum.Left:
{
this.Cursor = Cursors.SizeWE;
OriginalPoint = new Point(Locate.X + RectWidth - BorderWidth / 2, Locate.Y + RectHeight / 2);//右中部位置
TheoryWidth = OriginalPoint.X - MouseButtonLocate.X + BorderWidth;
TheoryHeight = IsRectangle == true ? TheoryWidth : RectHeight;
TheoryPoint = new Point(OriginalPoint.X + BorderWidth / 2 - TheoryWidth, OriginalPoint.Y - TheoryHeight / 2);
}
break;
case MouseLocationEnum.LeftUp:
{
this.Cursor = Cursors.SizeNWSE;
OriginalPoint = new Point(Locate.X + RectWidth - BorderWidth / 2, Locate.Y + RectHeight - BorderWidth / 2);//右下部位置
TheoryWidth = OriginalPoint.X - MouseButtonLocate.X + BorderWidth;
TheoryHeight = IsRectangle == true ? TheoryWidth : OriginalPoint.Y - MouseButtonLocate.Y + BorderWidth;
TheoryPoint = new Point(OriginalPoint.X + BorderWidth / 2 - TheoryWidth, OriginalPoint.Y + BorderWidth / 2 - TheoryHeight);
}
break;
case MouseLocationEnum.Up:
{
this.Cursor = Cursors.SizeNS;
OriginalPoint = new Point(Locate.X + RectWidth / 2, Locate.Y + RectHeight - BorderWidth / 2);//下中部位置
TheoryHeight = OriginalPoint.Y - MouseButtonLocate.Y + BorderWidth;
TheoryWidth = IsRectangle == true ? TheoryHeight : RectWidth;
TheoryPoint = new Point(OriginalPoint.X - TheoryWidth / 2, OriginalPoint.Y + BorderWidth / 2 - TheoryHeight);
}
break;
case MouseLocationEnum.RightUp:
{
this.Cursor = Cursors.SizeNESW;
OriginalPoint = new Point(Locate.X + BorderWidth / 2, Locate.Y + RectHeight - BorderWidth / 2);//左下部位置
TheoryWidth = MouseButtonLocate.X - OriginalPoint.X + BorderWidth;
TheoryHeight = IsRectangle == true ? TheoryWidth : MouseButtonLocate.Y - OriginalPoint.Y + BorderWidth;
TheoryPoint = new Point(OriginalPoint.X - BorderWidth / 2, OriginalPoint.Y + BorderWidth / 2 - TheoryHeight);
}
break;
case MouseLocationEnum.Right:
{
this.Cursor = Cursors.SizeWE;
OriginalPoint = new Point(Locate.X + BorderWidth / 2, Locate.Y + RectHeight / 2);//左中部位置
TheoryWidth = MouseButtonLocate.X - OriginalPoint.X + BorderWidth;
TheoryHeight = IsRectangle == true ? TheoryWidth : RectHeight;
TheoryPoint = new Point(OriginalPoint.X - BorderWidth / 2, OriginalPoint.Y - TheoryHeight / 2);
}
break;
case MouseLocationEnum.RightDown:
{
this.Cursor = Cursors.SizeNWSE;
OriginalPoint = new Point(Locate.X + BorderWidth / 2, Locate.Y + BorderWidth / 2);//左上部位置
TheoryWidth = MouseButtonLocate.X - OriginalPoint.X + BorderWidth;
TheoryHeight = IsRectangle == true ? TheoryWidth : MouseButtonLocate.Y - OriginalPoint.Y + BorderWidth;
TheoryPoint = new Point(OriginalPoint.X - BorderWidth / 2, OriginalPoint.Y - BorderWidth / 2);
}
break;
case MouseLocationEnum.Down:
{
this.Cursor = Cursors.SizeNS;
OriginalPoint = new Point(Locate.X + RectWidth / 2, Locate.Y + BorderWidth / 2);//上中部位置
TheoryHeight = MouseButtonLocate.Y - OriginalPoint.Y + BorderWidth;
TheoryWidth = IsRectangle == true ? TheoryHeight : RectWidth;
TheoryPoint = new Point(OriginalPoint.X - TheoryWidth / 2, OriginalPoint.Y - BorderWidth / 2);
}
break;
case MouseLocationEnum.LeftDown:
{
this.Cursor = Cursors.SizeNESW;
OriginalPoint = new Point(Locate.X + RectWidth - BorderWidth / 2, Locate.Y + BorderWidth / 2);//右上部位置
TheoryWidth = OriginalPoint.X - MouseButtonLocate.X + BorderWidth;
TheoryHeight = IsRectangle == true ? TheoryWidth : OriginalPoint.Y - MouseButtonLocate.Y + BorderWidth;
TheoryPoint = new Point(OriginalPoint.X + BorderWidth / 2 - TheoryWidth, OriginalPoint.Y - BorderWidth / 2);
}
break;
default:
return null;
}
return new RectangleAreaModel()
{
X = TheoryPoint.X,
Y = TheoryPoint.Y,
Width = TheoryWidth,
Height = TheoryHeight
};
}
/// <summary>
/// 图片剪切
/// </summary>
public void CutImage()
{
if (this.BitSource != null)
{
BitmapSource source = (BitmapSource)this.BitSource;
//计算比例
Point Locate = this.ImageArea.TransformToAncestor((UIElement)this.MainGrid).Transform(new Point(0, 0));
int dWidth = (int)((this.ImageArea.ActualWidth * 1.0 / this.MainGrid.ActualWidth) * source.PixelWidth);
int dHeight = (int)((this.ImageArea.ActualHeight * 1.0 / this.MainGrid.ActualHeight) * source.PixelHeight);
int dLeft = (int)((Locate.X * 1.0 / this.MainGrid.ActualWidth) * source.PixelWidth);
int dTop = (int)((Locate.Y * 1.0 / this.MainGrid.ActualHeight) * source.PixelHeight);
//像素区域
Int32Rect cutRect = new Int32Rect(dLeft, dTop, dWidth, dHeight);
//数组字节数
int stride = source.Format.BitsPerPixel * cutRect.Width / 8;
byte[] data = new byte[cutRect.Height * stride];
source.CopyPixels(cutRect, data, stride, 0);
//创建
BitmapSource bit = BitmapSource.Create(dWidth, dHeight, 0, 0, PixelFormats.Bgr32, null, data, stride);
//通知订阅
RaiseEvent(new RoutedEventArgs(OnCutImagingEventHandler, bit));
}
}
/// <summary>
/// 视图转图片
/// </summary>
/// <param name="vsual"></param>
/// <param name="nLeft"></param>
/// <param name="nTop"></param>
/// <param name="nWidth"></param>
/// <param name="nHeight"></param>
/// <returns></returns>
private RenderTargetBitmap RenderVisaulToBitmap(Visual vsual,int nLeft, int nTop,int nWidth, int nHeight)
{
var rtb = new RenderTargetBitmap(nWidth, nHeight, nLeft, nTop, PixelFormats.Default);
rtb.Render(vsual);
return rtb;
}
/// <summary>
/// Bitmap转图片
/// </summary>
/// <param name="bmp"></param>
/// <returns></returns>
public BitmapSource ToBitmapSource(System.Drawing.Bitmap bmp)
{
BitmapSource returnSource;
try
{
returnSource = System.Windows.Interop.Imaging.CreateBitmapSourceFromHBitmap(bmp.GetHbitmap(), IntPtr.Zero, Int32Rect.Empty, BitmapSizeOptions.FromEmptyOptions());
}
catch
{
returnSource = null;
}
return returnSource;
}
#endregion
#region ==事件==
//按下鼠标
private void UserControl_MouseDown(object sender, MouseButtonEventArgs e)
{
this.MouseLocation = Class.MouseLocationEnum.None;
if (e.OriginalSource.GetType() == typeof(Rectangle))
{
Rectangle Act = e.OriginalSource as Rectangle;
switch (Act.Name)
{
case "R_Left": MouseLocation = Class.MouseLocationEnum.Left; break;
case "R_LeftUp": MouseLocation = Class.MouseLocationEnum.LeftUp; break;
case "R_Up": MouseLocation = Class.MouseLocationEnum.Up; break;
case "R_RightUp": MouseLocation = Class.MouseLocationEnum.RightUp; break;
case "R_Right": MouseLocation = Class.MouseLocationEnum.Right; break;
case "R_RightDown": MouseLocation = Class.MouseLocationEnum.RightDown; break;
case "R_Down": MouseLocation = Class.MouseLocationEnum.Down; break;
case "R_LeftDown": MouseLocation = Class.MouseLocationEnum.LeftDown; break;
default: MouseLocation = Class.MouseLocationEnum.None; break;
}
this.Action = MouseActionEx.Drag;
}
else
{
this.MouseDownPoint = Mouse.GetPosition(e.Source as FrameworkElement);//WPF方法
this.MouseDownLocate = this.ImageArea.TransformToAncestor((UIElement)this.MainGrid).Transform(new Point(0, 0));
if ((this.MouseDownLocate.X < this.MouseDownPoint.X && this.MouseDownPoint.X < this.MouseDownLocate.X + this.ImageArea.ActualWidth) &&
(this.MouseDownLocate.Y < this.MouseDownPoint.Y && this.MouseDownPoint.Y < this.MouseDownLocate.Y + this.ImageArea.ActualHeight)
)
{
this.Action = MouseActionEx.DragMove;
}
}
}
//弹起鼠标
private void UserControl_MouseUp(object sender, MouseButtonEventArgs e)
{
this.Action = MouseActionEx.None;
this.Cursor = Cursors.Arrow;
}
//移动鼠标
private void UserControl_MouseMove(object sender, MouseEventArgs e)
{
//鼠标相对空间区域位置
Point MousePoint = e.GetPosition((IInputElement)this.MainGrid);
Point ImageLocate= this.ImageArea.TransformToAncestor((UIElement)this.MainGrid).Transform(new Point(0, 0));
if (ImageLocate.X <= MousePoint.X && MousePoint.X <= ImageLocate.X + this.ImageArea.ActualWidth &&
ImageLocate.Y <= MousePoint.Y && MousePoint.Y <= ImageLocate.Y + this.ImageArea.ActualHeight)
{
this.Cursor = Cursors.Hand;
}
else
{
this.Cursor = Cursors.Arrow;
}
//边框拉伸
if (this.Action == MouseActionEx.Drag)
{
this.Cursor = this.MouseCursor;
//剪辑图片区域宽高
double ImageAreaWidth = this.ImageArea.ActualWidth;
double ImageAreaHeight = this.ImageArea.ActualHeight;
//裁剪区域理论位置
RectangleAreaModel Model = this.CalculatedArea(MousePoint, true);
if (Model != null)
{
//不能超出边界区域
if (Model.X + Model.Width + MaxMargin > this.ActualWidth ||
Model.Y + Model.Height + MaxMargin > this.ActualHeight ||
Model.X < MaxMargin ||
Model.Y < MaxMargin
)
{
this.Cursor = Cursors.Arrow;
this.Action = MouseActionEx.None;
return;
}
this.ImageArea.Width = Model.Width;
this.ImageArea.Height = Model.Height;
this.ImageArea.SetValue(HorizontalAlignmentProperty, HorizontalAlignment.Left);
this.ImageArea.SetValue(VerticalAlignmentProperty, VerticalAlignment.Top);
this.ImageArea.SetValue(MarginProperty, new Thickness(Model.X, Model.Y, 0, 0));
CutImage();
}
}
else if (this.Action == MouseActionEx.DragMove)//拖动
{
double Left = this.MouseDownLocate.X + (MousePoint.X - MouseDownPoint.X);
double Top = this.MouseDownLocate.Y + (MousePoint.Y - MouseDownPoint.Y);
//不能超出边界区域
if (Left < MaxMargin ||
Top < MaxMargin ||
(Left + this.ImageArea.ActualWidth + MaxMargin) > this.ActualWidth ||
(Top + this.ImageArea.ActualHeight + MaxMargin) > this.ActualHeight)
{
this.Cursor = Cursors.Arrow;
this.Action = MouseActionEx.None;
return;
}
this.ImageArea.Width = this.ImageArea.ActualWidth;
this.ImageArea.Height = this.ImageArea.ActualHeight;
this.ImageArea.SetValue(HorizontalAlignmentProperty, HorizontalAlignment.Left);
this.ImageArea.SetValue(VerticalAlignmentProperty, VerticalAlignment.Top);
this.ImageArea.SetValue(MarginProperty, new Thickness(Left, Top, 0, 0));
CutImage();
}
else
{
//this.Cursor = Cursors.Arrow;
}
}
//鼠标离开
private void UserControl_MouseLeave(object sender, MouseEventArgs e)
{
this.Action = MouseActionEx.None;
}
#endregion
}
}
三、还需要一个蛋疼的辅助类
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace DialogEx.Class
{
/// <summary>
/// 鼠标八大位置枚举
/// </summary>
public enum MouseLocationEnum
{
None,
Left,
Up,
Right,
Down,
LeftUp,
LeftDown,
RightUp,
RightDown
}
/// <summary>
///
/// </summary>
public class RectangleAreaModel
{
public double X { get; set; }
public double Y { get; set; }
public double Width { get; set; }
public double Height { get; set; }
}
/// <summary>
/// 鼠标状态
/// </summary>
public enum MouseActionEx
{
/// <summary>
/// 无
/// </summary>
None,
/// <summary>
/// 拖拽
/// </summary>
Drag,
/// <summary>
/// 拖动
/// </summary>
DragMove
}
public enum SculptureAction
{
Nomal,
Video,
Image,
}
}
<pre name="code" class="csharp">界面使用
</pre><pre name="code" class="csharp">xmlns:MyControls="clr-namespace:DialogEx.Controls;assembly=DialogEx"
<MyControls:ImageDealer Panel.ZIndex="0" x:Name="ImageDealer" cal:Message.Attach="[Event OnCutImaging]=[Action OnCutImaging($EventArgs)]"></MyControls:ImageDealer>
/// <summary>
/// 截图中 - 实时
<span style="white-space:pre"> </span>/// </summary>
/// <param name="source"></param>
public void OnCutImaging(object source)
{
if (source != null && source.GetType() == typeof(RoutedEventArgs))
{
// if (((RoutedEventArgs)source).OriginalSource.GetType() == typeof(CroppedBitmap))
{
<pre name="code" class="csharp"><span style="white-space:pre"> </span>//得到了截图图片
BitmapSource CurBitMap = (BitmapSource)((RoutedEventArgs)source).OriginalSource;
//下面就是对接到的图片处理了。建议将图片保存在Image控件<span style="font-family: Arial, Helvetica, sans-serif;">中。界面上用ContentPresenter。
<span style="white-space:pre"> </span>}
}
}
五、关于明明截图成功,更换了头像。结果界面上显示的头像仍是以前的头像。
那么你肯能碰到这个问题了
http://blog.csdn.net/lvguoshan/article/details/47172109
六、最近刚根据本篇缺陷写了个升级版。由于篇幅问题重新写了一篇新的
http://blog.csdn.net/lvguoshan/article/details/48627031