WPF 自定义图片剪切器 - 头像剪切(扩展与完善、实时截图)
原文: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 自定义图片剪切器 - 头像剪切(扩展与完善、实时截图)的更多相关文章
- WPF 自定义图片按钮
此文档仅仅是一个BaseCode,已做后续查阅 XAML代码: <Button x:Class="IM.UI.UC.IM_ImageButton" xmlns="h ...
- WPF 自定义 MessageBox (相对完善版)
WPF 自定义 MessageBox (相对完善版) 基于WPF的自定义 MessageBox. 众所周知WPF界面美观.大多数WPF元素都可以简单的修改其样式,从而达到程序的风格统一.可是当 ...
- WPF 自定义 MessageBox (相对完善版 v1.0.0.6)
基于WPF的自定义 MessageBox. 众所周知WPF界面美观.大多数WPF元素都可以简单的修改其样式,从而达到程序的风格统一.可是当你不得不弹出一个消息框通知用户消息时(虽然很不建议在程序中频繁 ...
- vue自定义指令clickoutside使用以及扩展用法
vue自定义指令clickoutside使用以及扩展用法 产品使用vue+element作为前端框架.在功能开发过程中,难免遇到使用element的组件没办法满足特殊的业务需要,需要对其进行定制,例如 ...
- WPF自定义TextBox及ScrollViewer
原文:WPF自定义TextBox及ScrollViewer 寒假过完,在家真心什么都做不了,可能年龄大了,再想以前那样能专心坐下来已经不行了.回来第一件事就是改了项目的一个bug,最近又新增了一个新的 ...
- ASP.NET实现头像剪切保存
利用swfupload上传头像,利用Jcrop来实现头像在线选择,然后提交个ashx对原头像进行剪切.代码如下: default.aspx: <%@ Page Language="C# ...
- WPF 自定义ComboBox样式,自定义多选控件
原文:WPF 自定义ComboBox样式,自定义多选控件 一.ComboBox基本样式 ComboBox有两种状态,可编辑和不可编辑状态.通过设置IsEditable属性可以切换控件状态. 先看基本样 ...
- WPF 自定义MenuItem样式
原文:WPF 自定义MenuItem样式 一.前言 默认的MenuItem样式比较普通,这次自定义MenuItem的样式也只是对MenuItem的颜色风格进行变化.需要其他功能的变化,大家可以根据样式 ...
- 使用WPF将图片转变为灰度并加上水印并保存为文件
原文:使用WPF将图片转变为灰度并加上水印并保存为文件 运行效果: (上图中左下角为原图的缩小显示,By:Johnson为TextBlock)保存的结果图片:上图的"Test Words.& ...
随机推荐
- Jedis 源代码阅读一 —— Jedis
这是jedis 源代码文件夹,我们接下来选择性阅读重要的接口以及实现. └─redis └─clients ├─jedis │ │ BinaryClient.java │ │ BinaryJedis. ...
- 菜单之一:Menu基础内容 分类: H1_ANDROID 2013-11-03 00:23 906人阅读 评论(0) 收藏
参考<疯狂android讲义>2.10节P168 1.重要接口 Android菜单相关的重要接口共有以下四个: 其中Menu为普通菜单,SubMenu包含子项,ContextMenu当长时 ...
- Notepad++打开xml文件显示crlf的问题
如图所示,显示CRLF, CRLF其实是换行符. 所以在下图所示设置下显示行尾符不显示即可.
- Wow6432Node(32位程序的注册表内容都在这个节点下,也可直接使用%systemroot%\syswow64\regedit进行编辑)
64 位版本 Windows 中的注册表分为 32 位注册表项和 64 位注册表项.许多 32 位注册表项与其相应的 64 位注册表项同名,反之亦然. 64 位版本 Windows 包含的默认 64 ...
- css3-1 css3游戏介绍、css3样式和优先级
css3-1 css3游戏介绍.css3样式和优先级 一.总结 一句话总结:我们写外部css表的时候可以用class,那样使用的人用id修改的话优先级就比我们高,达到目的. 1.html嵌套css样式 ...
- AngularJS之基本指令(init、repeat)
<h3>ng-init初始化变量</h3> <div ng-init="name='aurora';age='18'"> <p ng-bi ...
- 在Android实现client授权
OAuth对你的数据和服务正在变成实际上的同意訪问协议在没有分享用户password. 实际上全部的有名公司像Twitter.Google,Yahoo或者LinkedIn已经实现了它.在全部流行的程序 ...
- Chrome谷歌浏览器web前端开发好用插件(自己用)备忘
Chrome谷歌浏览器web前端开发好用插件(自己用)备忘 一.总结 英语好一点的话要什么工具就直接去Chrome插件里面找非常方便. 二.测试题-简答题 1.Chrome修改页面字符集是什么? 解答 ...
- spring mvc redirect 重定向 跳转并传递参数
在项目中做form表单功能提交时,防止用户客户端后退或者刷新时重复提交问题,需要在服务端进行重定向跳转,具体跳转方式有以下几种方式: 公用代码: @RequestMapping(value=" ...
- js进阶 10-4 jquery中基础选择器有哪些
js进阶 10-4 jquery中基础选择器有哪些 一.总结 一句话总结: 1.群组选择器用的符号是什么? 群组选择器,中间是逗号 2.jquery中基础选择器有哪些? 5种,类,id,tag,群组, ...