原文:WPF 自定义图片剪切器 - 头像剪切(扩展与完善、实时截图)

一、说明:上一次写的WPF
自定义图片剪切器 - 头像剪切。你懂得
存在明显的缺陷,由于篇幅较长。重新写了一篇新的。

问题的原因:由于是对图片文件进行剪切处理,当图片加载后变形的话,处理起来明显的有错误!

解决办法:重新计算比例。但是有个问题就是在原来的基础上重新计算,计算量会相当复杂。因为整个截图区域就那么大,是固          定的,而图片可大可小,你要是想正确获取加载后的图片与截图区域的比例将会变得相当麻烦。

所以,本次采用一个最基本的设计技巧,就是 截图区域 = 图片加载后的区域 !将截图控件ImageDealerUnsafe按照大小可变化的情况封装在自定义控件ImageDealer里,通过自定义控件ImageDealer封装截图控件的调用接口,而ImageDealerUnsafe。

二、关于截图控件(ImageDealerUnsafe)  用户不应调用该控件的任何方法、仅供ImageDealer调用

1、截图控件 ImageDealerUnsafe XAML

<UserControl x:Class="DialogEx.Controls.Unsafe.ImageDealerUnsafe"
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" >
<Image Name="SoureceImage" Stretch="Uniform"></Image>
<Border Name="ImageArea" BorderBrush="Red" BorderThickness="1,1,1,1" Panel.ZIndex="5" Margin="50" SizeChanged="ImageArea_SizeChanged">
<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>

2、截图控件ImageDealerUnsafeCS

using DialogEx.Class;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
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.Unsafe
{
/// <summary>
/// ImageDealerUnsafe.xaml 的交互逻辑
/// </summary>
public partial class ImageDealerUnsafe : UserControl
{ #region 公共字段
//截图回调
public delegate void CutImageDelegate(BitmapSource bit);
public CutImageDelegate OnCutImage;
//图片原
private BitmapImage _BitSource;
public BitmapImage BitSource
{
get { return this._BitSource; }
set
{
this._BitSource = value;
this.SoureceImage.Source = value;
}
}
#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 ImageDealerUnsafe()
{
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)
{
try
{
double ImageAreaWidth = this.ImageArea.ActualWidth;
double ImageAreaHeight = this.ImageArea.ActualHeight;
double GridWidth = this.MainGrid.ActualWidth;
double GridHeight = this.MainGrid.ActualHeight; BitmapSource source = (BitmapSource)this.BitSource;
//计算比例
Point Locate = this.ImageArea.TransformToAncestor((UIElement)this.MainGrid).Transform(new Point(0, 0));
int dWidth = (int)((ImageAreaWidth * 1.0 / GridWidth) * source.PixelWidth);
int dHeight = (int)((ImageAreaHeight * 1.0 / GridHeight) * source.PixelHeight);
int dLeft = (int)((Locate.X * 1.0 / GridWidth) * source.PixelWidth);
int dTop = (int)((Locate.Y * 1.0 / GridHeight) * 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);
//通知订阅
if (this.OnCutImage != null)
{
OnCutImage(bit);
}
}
catch
{ }
}
}
/// <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; }
//加载完成后截图
private void ImageArea_SizeChanged(object sender, SizeChangedEventArgs e)
{
this.CutImage();
} #endregion
}
}

三、封装的截图工具 ImageDealer

1、ImageDealer XAML

<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"
Loaded="UserControl_Loaded"
>
<Grid Name="MainGrid" MinHeight="200" MinWidth="200" >
</Grid>
</UserControl>

2、ImageDealer CS

using DialogEx.Class;
using DialogEx.Controls.Unsafe;
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
{
public static readonly RoutedEvent OnCutImagingEventHandler = EventManager.RegisterRoutedEvent("OnCutImaging", RoutingStrategy.Bubble, typeof(RoutedEventHandler), typeof(ImageDealer)); #region 私有字段
/// <summary>
/// 截图控件
/// </summary>
private ImageDealerUnsafe _ImageDealerControl = new ImageDealerUnsafe();
/// <summary>
/// 图片源
/// </summary>
private BitmapImage _BitSource;
private int _ChangeMargin = 1;
#endregion #region 公共字段 /// <summary>
/// 图片源
/// </summary>
public BitmapImage BitSource
{
get { return this._BitSource; }
set
{
this._BitSource = value;
this._ImageDealerControl.BitSource = value;
LocateInit();
}
} /// <summary>
/// 截图事件
/// </summary>
public event RoutedEventHandler OnCutImaging
{
add { base.AddHandler(OnCutImagingEventHandler, value); }
remove { base.RemoveHandler(OnCutImagingEventHandler, value); }
} #endregion #region ==方法== public ImageDealer()
{
InitializeComponent();
this._ImageDealerControl.OnCutImage += this.OnCutImage;
}
//外部截图
public void CutImage()
{
if (this.IsLoaded == true || this._ImageDealerControl == null)
{
this._ImageDealerControl.CutImage();
}
else
{
throw new Exception("尚未创建视图时无法截图!");
}
}
//截图控件位置初始化
private void LocateInit()
{
double Margin = 1;
if (this._BitSource != null)
{
double percent = 1;
//根据最小倍率放大截图控件
percent = (this._BitSource.PixelHeight * 1.0 / this.ActualHeight);
percent = percent < (this._BitSource.PixelWidth * 1.0 / this.ActualWidth) ? (this._BitSource.PixelWidth * 1.0 / this.ActualWidth) : percent;
this._ImageDealerControl.Width = this._BitSource.PixelWidth * 1.0 / percent;
this._ImageDealerControl.Height = this._BitSource.PixelHeight * 1.0 / percent;
//初始化截图方块
this._ImageDealerControl.ImageArea.Width = this._ImageDealerControl.ImageArea.Height = 100 + _ChangeMargin ;
_ChangeMargin = -_ChangeMargin;
this._ImageDealerControl.ImageArea.SetValue(VerticalAlignmentProperty, VerticalAlignment.Center);
this._ImageDealerControl.ImageArea.SetValue(HorizontalAlignmentProperty, HorizontalAlignment.Center);
this._ImageDealerControl.ImageArea.SetValue(MarginProperty, new Thickness(0));
//截图控件相对父控件Margin
this._ImageDealerControl.Width -= 2 * Margin;
this._ImageDealerControl.Height -= 2 * Margin;
this._ImageDealerControl.SetValue(VerticalAlignmentProperty, VerticalAlignment.Center);
this._ImageDealerControl.SetValue(HorizontalAlignmentProperty, HorizontalAlignment.Center);
this._ImageDealerControl.SetValue(MarginProperty, new Thickness(0));
}
} #endregion #region ==事件== //截图回调
private void OnCutImage(BitmapSource bit)
{
RaiseEvent(new RoutedEventArgs(OnCutImagingEventHandler, bit));
}
//加载完成
private void UserControl_Loaded(object sender, RoutedEventArgs e)
{
if (this.MainGrid.Children.Contains(this._ImageDealerControl) == false)
{
this.MainGrid.Children.Add(this._ImageDealerControl);
this._ImageDealerControl.Width = this.ActualWidth;
this._ImageDealerControl.Height = this.ActualHeight;
this._ImageDealerControl.SetValue(VerticalAlignmentProperty, VerticalAlignment.Center);
this._ImageDealerControl.SetValue(HorizontalAlignmentProperty, HorizontalAlignment.Center);
this._ImageDealerControl.SetValue(MarginProperty, new Thickness(0));
}
} #endregion }
}

四、用户调用

1、外部调用 Windows 的 XAML

xmlns:MyControls="clr-namespace:DialogEx.Controls;assembly=DialogEx"

<!--图片选择区域-->
<pre name="code" class="csharp" style="font-size: 14px;"><Grid Visibility="{Binding ImageVisible}">
<MyControls:ImageDealer Panel.ZIndex="0" x:Name="ImageDealer" <span style="font-family: Arial, Helvetica, sans-serif;">OnCutImaging</span><span style="font-family: Arial, Helvetica, sans-serif;">="</span><span style="font-family: Arial, Helvetica, sans-serif;">OnCutImaging"></MyControls:ImageDealer></span>
</Grid>


2、Windows 的 CS

包含两个方法

1、获取截图控件的截取的图片(被动的接收通知、回调)

2、保存头像文件、(加载头像的时候请使用缓存方式

 private BitmapSource CurBitMap;

<span style="white-space:pre">	</span>/// <summary>
<span style="white-space:pre"> </span>/// 截图中
<span style="white-space:pre"> </span>/// </summary>
<span style="white-space:pre"> </span>/// <param name="source"></param>
public void OnCutImaging(object source)
{
if (source != null && source.GetType() == typeof(RoutedEventArgs))
{
// if (((RoutedEventArgs)source).OriginalSource.GetType() == typeof(CroppedBitmap))
{
CurBitMap = (BitmapSource)((RoutedEventArgs)source).OriginalSource;
}
}
} <span style="white-space:pre"> </span>/// <summary>
/// 保存头像
/// </summary>
public void btnCutPicture_Click()
{
string strFilePath = "F:\\1.png";
//try
{
if (File.Exists(strFilePath) == true)
{
File.Delete(strFilePath);
}
JpegBitmapEncoder encoder = new JpegBitmapEncoder();
encoder.Frames.Add(BitmapFrame.Create(this.CurBitMap)); FileStream fileStream = new FileStream(strFilePath, FileMode.Create, FileAccess.ReadWrite);
encoder.Save(fileStream);
fileStream.Close();
}
//catch
{ } }

WPF 自定义图片剪切器 - 头像剪切(扩展与完善、实时截图)的更多相关文章

  1. WPF 自定义图片按钮

    此文档仅仅是一个BaseCode,已做后续查阅 XAML代码: <Button x:Class="IM.UI.UC.IM_ImageButton" xmlns="h ...

  2. WPF 自定义 MessageBox (相对完善版)

    WPF 自定义 MessageBox (相对完善版)     基于WPF的自定义 MessageBox. 众所周知WPF界面美观.大多数WPF元素都可以简单的修改其样式,从而达到程序的风格统一.可是当 ...

  3. WPF 自定义 MessageBox (相对完善版 v1.0.0.6)

    基于WPF的自定义 MessageBox. 众所周知WPF界面美观.大多数WPF元素都可以简单的修改其样式,从而达到程序的风格统一.可是当你不得不弹出一个消息框通知用户消息时(虽然很不建议在程序中频繁 ...

  4. vue自定义指令clickoutside使用以及扩展用法

    vue自定义指令clickoutside使用以及扩展用法 产品使用vue+element作为前端框架.在功能开发过程中,难免遇到使用element的组件没办法满足特殊的业务需要,需要对其进行定制,例如 ...

  5. WPF自定义TextBox及ScrollViewer

    原文:WPF自定义TextBox及ScrollViewer 寒假过完,在家真心什么都做不了,可能年龄大了,再想以前那样能专心坐下来已经不行了.回来第一件事就是改了项目的一个bug,最近又新增了一个新的 ...

  6. ASP.NET实现头像剪切保存

    利用swfupload上传头像,利用Jcrop来实现头像在线选择,然后提交个ashx对原头像进行剪切.代码如下: default.aspx: <%@ Page Language="C# ...

  7. WPF 自定义ComboBox样式,自定义多选控件

    原文:WPF 自定义ComboBox样式,自定义多选控件 一.ComboBox基本样式 ComboBox有两种状态,可编辑和不可编辑状态.通过设置IsEditable属性可以切换控件状态. 先看基本样 ...

  8. WPF 自定义MenuItem样式

    原文:WPF 自定义MenuItem样式 一.前言 默认的MenuItem样式比较普通,这次自定义MenuItem的样式也只是对MenuItem的颜色风格进行变化.需要其他功能的变化,大家可以根据样式 ...

  9. 使用WPF将图片转变为灰度并加上水印并保存为文件

    原文:使用WPF将图片转变为灰度并加上水印并保存为文件 运行效果: (上图中左下角为原图的缩小显示,By:Johnson为TextBlock)保存的结果图片:上图的"Test Words.& ...

随机推荐

  1. ios开发swift学习第三天:逻辑分支

    一. 分支的介绍 分支即if/switch/三目运算符等判断语句 通过分支语句可以控制程序的执行流程 二. if分支语句 和OC中if语句有一定的区别 判断句可以不加() 在Swift的判断句中必须有 ...

  2. ios开发核心动画五:图标抖动效果--CAKeyframeAnimation

    #import "ViewController.h" #define angle2Rad(angle) ((angle) / 180.0 * M_PI) @interface Vi ...

  3. 字符串函数(strcpy字符串拷,strcmp字符串比较,strstr字符串查找,strDelChar字符串删除字符,strrev字符串反序,memmove拷贝内存块,strlen字符串长度)

    1.strcpy字符串拷贝拷贝pStrSource到pStrDest,并返回pStrDest地址(源和目标位置重叠情况除外) char *strcpy(char *pStrDest, const ch ...

  4. python排序查找

    无序表查找 def seq_search(lst, key): found = False pos = 0 while pos < len(lst) and not found: if lst[ ...

  5. Hadoop源码分析(MapReduce概论)

    大家都熟悉文件系统,在对HDFS进行分析前,我们并没有花非常多的时间去介绍HDFS的背景.毕竟大家对文件系统的还是有一定的理解的,并且也有非常好的文档.在分析Hadoop的MapReduce部分前,我 ...

  6. Distribution download cancelled. Using distribution from 'https://services.gradle.org/distributions/

    Distribution download cancelled. Using distribution from ‘https://services.gradle.org/distributions/ ...

  7. 【u022】车的放置

    [问题描述] [题解] 先考虑一个最简单的情况.如一个n*n的棋盘.然后要放k个车. 我们可以先选出k行即C(n,k); 然后在列上对这k个棋子进行一次全排列即A(n,k); 比如k = 4;N=5 ...

  8. [React Router v4] Use the React Router v4 Link Component for Navigation Between Routes

    If you’ve created several Routes within your application, you will also want to be able to navigate ...

  9. Java Web 实用返回结果封装

    实用的返回结果封装 使用示例 效果 Result ResultEnum 使用示例 /** * @Author: huangwenjun * @Description: * @Date: Created ...

  10. 【codeforces 785B】Anton and Classes

    [题目链接]:http://codeforces.com/contest/785/problem/B [题意] 给你两个时间各自能够在哪些时间段去完成; 让你选择两个时间段来完成这两件事情; 要求两段 ...