Win10 for Phone 裁剪控件
<Page.BottomAppBar>
<CommandBar x:Name="appBar">
<AppBarButton Label="裁切" Icon="Crop" Click="AppBarButton_Crop_Click">
</AppBarButton>
<AppBarButton Label="完成" Icon="Accept" Click="AppBarButton_Accept_Click">
</AppBarButton>
</CommandBar>
</Page.BottomAppBar> <Grid x:Name="LayoutRoot" Background="Transparent">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Image Name="CroppedImage"
Grid.Row=""
CacheMode="BitmapCache" ManipulationMode="All"
PointerPressed="CroppedImage_PointerPressed"
PointerReleased="CroppedImage_PointerReleased"
PointerMoved="CroppedImage_PointerMoved">
<!--<Image.Clip>
<RectangleGeometry x:Name="ClipRect"/>
</Image.Clip>-->
</Image>
<Canvas Name="CropCanvas"
Grid.RowSpan="">
<Rectangle Name="LeftBack"
HorizontalAlignment="Left"
VerticalAlignment="Top"
Fill="#99000000"
IsHitTestVisible="False"/>
<Rectangle Name="TopBack"
HorizontalAlignment="Left"
VerticalAlignment="Top"
Fill="#99000000"
IsHitTestVisible="False"/>
<Rectangle Name="RightBack"
HorizontalAlignment="Left"
VerticalAlignment="Top"
Fill="#99000000"
IsHitTestVisible="False"/>
<Rectangle Name="BottomBack"
HorizontalAlignment="Left"
VerticalAlignment="Top"
Fill="#99000000"
IsHitTestVisible="False"/>
<TextBlock Name="SizeLabel"
Width=""
TextAlignment="Right"
FontSize=""
Foreground="Gray"
IsHitTestVisible="False"
FontFamily="{StaticResource PhoneFontFamilyNormal}"/>
<Rectangle Name="TL"
Height=""
HorizontalAlignment="Left"
VerticalAlignment="Top"
Width=""
StrokeThickness=""
Stroke="Transparent"
IsHitTestVisible="False"
Fill="Transparent"
Canvas.Left="{x:Bind PinTL.Left,Mode=OneWay}"
Canvas.Top="{x:Bind PinTL.Top,Mode=OneWay}"/>
<Rectangle Name="TR"
Height=""
HorizontalAlignment="Left"
VerticalAlignment="Top"
Width=""
StrokeThickness=""
Stroke="Transparent"
IsHitTestVisible="False"
Fill="Transparent"
Canvas.Left="{x:Bind PinTR.Left,Mode=OneWay}"
Canvas.Top="{x:Bind PinTR.Top,Mode=OneWay}"/>
<Rectangle Name="BL"
Height=""
HorizontalAlignment="Left"
VerticalAlignment="Top"
Width=""
StrokeThickness=""
Stroke="Transparent"
IsHitTestVisible="False"
Fill="Transparent"
Canvas.Left="{x:Bind PinBL.Left,Mode=OneWay}"
Canvas.Top="{x:Bind PinBL.Top,Mode=OneWay}"/>
<Rectangle Name="BR"
Height=""
HorizontalAlignment="Left"
VerticalAlignment="Top"
Width=""
StrokeThickness=""
Stroke="Transparent"
IsHitTestVisible="False"
Fill="Transparent"
Canvas.Left="{x:Bind PinBR.Left,Mode=OneWay}"
Canvas.Top="{x:Bind PinBR.Top,Mode=OneWay}"/>
</Canvas>
</Grid>
#region 常量
private Rectangle activePin; private const double doublePinSize = ; private const double halfPinSize = ; private bool isNew; private double minHeight; private double minWidth; private bool moveRect; private Point offset; private PinRect PinBL; private PinRect PinBR; private const double pinSize = ; private PinRect PinTL; private PinRect PinTR; private int realHeight; private int realWidth; private double scale; private int startX; private int startY; private Point tapDiff; #endregion
BitmapImage mSourceBitmap;
public PhotoChooserPage()
{
this.InitializeComponent(); SizeChangedEventHandler sizeChangedEventHandler = null; this.tapDiff = new Point(, );
this.scale = ;
this.minWidth = ;
this.minHeight = ;
this.PinTL = new PinRect();
this.PinBL = new PinRect();
this.PinTR = new PinRect();
this.PinBR = new PinRect();
this.TL.DataContext = this.PinTL;
this.BL.DataContext = this.PinBL;
this.TR.DataContext = this.PinTR;
this.BR.DataContext = this.PinBR;
Image croppedImage = this.CroppedImage;
if (sizeChangedEventHandler == null)
{
sizeChangedEventHandler = (object s, SizeChangedEventArgs e) => this.InitImage();
}
croppedImage.SizeChanged += sizeChangedEventHandler; }
private void InitImage()
{
if (this.isNew)
{
this.isNew = false;
GeneralTransform visual = this.CroppedImage.TransformToVisual(Window.Current.Content);
this.offset = visual.TransformPoint(new Point(, ));
Size renderSize = this.CroppedImage.RenderSize;
this.scale = renderSize.Width / (double)mSourceBitmap.PixelWidth;
double num = this.scale * ;
ForUserInit();
}
}
void ForUserInit()
{
this.minWidth = ;
this.minHeight = ; Size renderSize = this.CroppedImage.RenderSize;
double left = ;
double right = ; if (renderSize.Width > )
left = (renderSize.Width - ) / ; if (renderSize.Height > )
right = (renderSize.Height - ) / ; double x = this.offset.X + left;
double y = this.offset.Y + right; //左上角
this.PinTL.RealLeft = x;
this.PinTL.RealTop = y; //左下角
this.PinBL.RealLeft = x;
this.PinBL.RealTop = y + this.minHeight - ; //右上角
this.PinTR.RealLeft = x + this.minWidth - ;
this.PinTR.RealTop = y; //右下角
this.PinBR.RealLeft = x + this.minWidth - ;
this.PinBR.RealTop = y + this.minHeight - ;
this.CroppedImage_PointerMoved(null, null);
} protected override void OnNavigatedTo(NavigationEventArgs e)
{
if (e.NavigationMode == NavigationMode.New)
{
// 如果用户选择了图片,则显示在屏幕上
mSourceBitmap = e.Parameter as BitmapImage;
//CroppedImage
CroppedImage.Source = mSourceBitmap;
isNew = true;
}
} private void CroppedImage_PointerPressed(object sender, PointerRoutedEventArgs e)
{
Point position = e.GetCurrentPoint(this.CroppedImage).Position;
this.activePin = null;
this.moveRect = false;
if (this.IsRectTapped(position.X + this.offset.X, position.Y + this.offset.Y))
{
this.moveRect = true;
}
if (this.IsPinTapped(this.PinTL, position.X + this.offset.X, position.Y + this.offset.Y))
{
this.activePin = this.TL;
}
if (this.IsPinTapped(this.PinTR, position.X + this.offset.X, position.Y + this.offset.Y))
{
this.activePin = this.TR;
}
if (this.IsPinTapped(this.PinBL, position.X + this.offset.X, position.Y + this.offset.Y))
{
this.activePin = this.BL;
}
if (this.IsPinTapped(this.PinBR, position.X + this.offset.X, position.Y + this.offset.Y))
{
this.activePin = this.BR;
}
} private void CroppedImage_PointerReleased(object sender, PointerRoutedEventArgs e)
{
this.moveRect = false;
this.activePin = null;
} private void CroppedImage_PointerMoved(object sender, PointerRoutedEventArgs e)
{
Point position;
if (e != null)
{
position = e.GetCurrentPoint(this.CroppedImage).Position;
}
else
{
Point point = new Point();
position = point;
}
Point point1 = position;
double x = point1.X + this.offset.X + this.tapDiff.X;
double y = point1.Y + this.offset.Y + this.tapDiff.Y;
double realLeft = this.PinBR.RealLeft - this.PinTL.RealLeft;
double realTop = this.PinBR.RealTop - this.PinTL.RealTop; if (this.activePin == null)
{
if (this.moveRect)
{
if (x < this.offset.X)
{
x = this.offset.X;
}
Size renderSize = this.CroppedImage.RenderSize;
if (x > this.offset.X + renderSize.Width - realLeft - )
{
Size size = this.CroppedImage.RenderSize;
x = this.offset.X + size.Width - realLeft - ;
}
if (y < this.offset.Y)
{
y = this.offset.Y;
}
Size renderSize1 = this.CroppedImage.RenderSize;
if (y > this.offset.Y + renderSize1.Height - realTop - )
{
Size size1 = this.CroppedImage.RenderSize;
y = this.offset.Y + size1.Height - realTop - ;
}
this.PinTL.RealLeft = x;
this.PinTL.RealTop = y;
this.PinBL.RealLeft = x;
this.PinBL.RealTop = y + realTop;
this.PinBR.RealLeft = x + realLeft;
this.PinBR.RealTop = y + realTop;
this.PinTR.RealLeft = x + realLeft;
this.PinTR.RealTop = y;
}
}
else
this.MoveInRatio(x, ); Point imageSize = this.GetImageSize();
this.LeftBack.SetValue(Canvas.LeftProperty, this.offset.X);
this.LeftBack.SetValue(Canvas.TopProperty, this.offset.Y);
this.LeftBack.Height = Math.Max(, Math.Ceiling(imageSize.Y));
this.LeftBack.Width = Math.Max(, (double)this.PinTL.Left - this.offset.X); this.RightBack.SetValue(Canvas.LeftProperty, (double)this.PinBR.Left + );
this.RightBack.SetValue(Canvas.TopProperty, this.offset.Y);
this.RightBack.Height = Math.Max(, Math.Ceiling(imageSize.Y));
this.RightBack.Width = Math.Max(, Math.Ceiling(imageSize.X) + this.offset.X - - (double)this.PinBR.Left); this.TopBack.SetValue(Canvas.LeftProperty, (double)this.PinTL.Left);
this.TopBack.SetValue(Canvas.TopProperty, this.offset.Y);
this.TopBack.Height = Math.Max(, (double)this.PinTL.Top - this.offset.Y);
this.TopBack.Width = Math.Max(, (double)(this.PinBR.Left - this.PinTL.Left) + ); this.BottomBack.SetValue(Canvas.LeftProperty, (double)this.PinTL.Left);
this.BottomBack.SetValue(Canvas.TopProperty, (double)this.PinBR.Top + );
this.BottomBack.Height = Math.Max(, Math.Ceiling(imageSize.Y) + this.offset.Y - - (double)this.PinBR.Top);
this.BottomBack.Width = Math.Max(, (double)(this.PinBR.Left - this.PinTL.Left) + ); realLeft = this.PinBR.RealLeft - this.PinTL.RealLeft;
realTop = this.PinBR.RealTop - this.PinTL.RealTop; this.startX = (int)Math.Round((this.PinTL.RealLeft - this.offset.X) / this.scale);
this.startY = (int)Math.Round((this.PinTL.RealTop - this.offset.Y) / this.scale);
this.realWidth = (int)Math.Round((realLeft + ) / this.scale);
this.realHeight = (int)Math.Round((realTop + ) / this.scale);
}
private Point GetImageSize()
{
Size renderSize = this.CroppedImage.RenderSize;
if (renderSize.Height == )
{
Size size = this.CroppedImage.RenderSize;
if (size.Width == )
{
return new Point(this.CroppedImage.ActualWidth, this.CroppedImage.ActualHeight);
}
}
Size renderSize1 = this.CroppedImage.RenderSize;
Size size1 = this.CroppedImage.RenderSize;
return new Point(renderSize1.Width, size1.Height);
}
private bool IsPinTapped(PinRect pin, double left, double top)
{
bool flag;
if (left < pin.RealLeft - || left > pin.RealLeft + || top < pin.RealTop - )
{
flag = false;
}
else
{
flag = top <= pin.RealTop + ;
}
bool flag1 = flag;
if (flag1)
{
this.tapDiff = new Point(pin.RealLeft - left, pin.RealTop - top);
}
return flag1;
}
private bool IsRectTapped(double left, double top)
{
Rect rect = new Rect(this.PinTL.RealLeft, this.PinTL.RealTop, this.PinBR.RealLeft + , this.PinBR.RealTop + );
bool flag = rect.Contains(new Point(left, top));
if (flag)
{
this.tapDiff = new Point(this.PinTL.RealLeft - left, this.PinTL.RealTop - top);
}
return flag;
}
private void MoveInRatio(double y, double rate)
{
if (this.activePin.Equals(this.BR))
{
double x = y;
double realLeft = (x + - this.PinTL.RealLeft) / rate + this.PinTL.RealTop - ;
Size renderSize = this.CroppedImage.RenderSize;
if (x > this.offset.X + renderSize.Width - )
{
Size size = this.CroppedImage.RenderSize;
x = this.offset.X + size.Width - ;
realLeft = (x + - this.PinTL.RealLeft) / rate + this.PinTL.RealTop - ;
}
Size renderSize1 = this.CroppedImage.RenderSize;
if (realLeft > this.offset.Y + renderSize1.Height - )
{
Size size1 = this.CroppedImage.RenderSize;
realLeft = this.offset.Y + size1.Height - ;
x = (realLeft + - this.PinTL.RealTop) * rate + this.PinTL.RealLeft - ;
}
if (x < this.PinTL.RealLeft + this.minWidth - )
{
x = this.PinTL.RealLeft + this.minWidth - ;
realLeft = this.PinTL.RealTop + this.minHeight - ;
}
this.PinTR.RealLeft = x;
this.PinBL.RealTop = realLeft;
this.PinBR.RealLeft = x;
this.PinBR.RealTop = realLeft;
}
if (this.activePin.Equals(this.TR))
{
double realTop = y;
double num = this.PinBL.RealTop - (realTop + - this.PinBL.RealLeft) / rate + ;
Size renderSize2 = this.CroppedImage.RenderSize;
if (realTop > this.offset.X + renderSize2.Width - )
{
Size size2 = this.CroppedImage.RenderSize;
realTop = this.offset.X + size2.Width - ;
num = this.PinBL.RealTop - (realTop + - this.PinBL.RealLeft) / rate + ;
}
if (num < this.offset.Y)
{
num = this.offset.Y;
realTop = (this.PinBL.RealTop - num + ) * rate + this.PinBL.RealLeft - ;
}
if (realTop < this.PinBL.RealLeft + this.minWidth - )
{
realTop = this.PinBL.RealLeft + this.minWidth - ;
num = this.PinBL.RealTop - this.minHeight + ;
}
this.PinBR.RealLeft = realTop;
this.PinTL.RealTop = num;
this.PinTR.RealLeft = realTop;
this.PinTR.RealTop = num;
}
if (this.activePin.Equals(this.TL))
{
double realLeft1 = y;
double realTop1 = this.PinBR.RealTop - (this.PinBR.RealLeft + - realLeft1) / rate + ;
if (realLeft1 > this.PinBR.RealLeft + - this.minWidth)
{
realLeft1 = this.PinBR.RealLeft + - this.minWidth;
realTop1 = this.PinBR.RealTop + - this.minHeight;
}
if (realTop1 < this.offset.Y)
{
realTop1 = this.offset.Y;
realLeft1 = this.PinBR.RealLeft + - (this.PinBR.RealTop - realTop1 + ) * rate;
}
if (realLeft1 < this.offset.X)
{
realLeft1 = this.offset.X;
realTop1 = this.PinBR.RealTop - (this.PinBR.RealLeft + - realLeft1) / rate + ;
}
this.PinBL.RealLeft = realLeft1;
this.PinTR.RealTop = realTop1;
this.PinTL.RealLeft = realLeft1;
this.PinTL.RealTop = realTop1;
}
if (this.activePin.Equals(this.BL))
{
double x1 = y;
double num1 = (this.PinTR.RealLeft + - x1) / rate + this.PinTR.RealTop - ;
if (x1 > this.PinTR.RealLeft + - this.minWidth)
{
x1 = this.PinTR.RealLeft + - this.minWidth;
num1 = this.PinTR.RealTop + this.minHeight - ;
}
Size renderSize3 = this.CroppedImage.RenderSize;
if (num1 > this.offset.Y + renderSize3.Height - )
{
Size size3 = this.CroppedImage.RenderSize;
num1 = this.offset.Y + size3.Height - ;
x1 = this.PinTR.RealLeft - (num1 + - this.PinTR.RealTop) * rate + ;
}
if (x1 < this.offset.X)
{
x1 = this.offset.X;
num1 = (this.PinTR.RealLeft + - x1) / rate + this.PinTR.RealTop - ;
}
this.PinTL.RealLeft = x1;
this.PinBR.RealTop = num1;
this.PinBL.RealLeft = x1;
this.PinBL.RealTop = num1;
}
}
public static WriteableBitmap writeableBmp;
private async void AppBarButton_Crop_Click(object sender, RoutedEventArgs e)
{ } private void AppBarButton_Accept_Click(object sender, RoutedEventArgs e)
{ }
Win10 for Phone 裁剪控件的更多相关文章
- Android开发技巧——定制仿微信图片裁剪控件
拍照--裁剪,或者是选择图片--裁剪,是我们设置头像或上传图片时经常需要的一组操作.上篇讲了Camera的使用,这篇讲一下我对图片裁剪的实现. 背景 下面的需求都来自产品. 裁剪图片要像微信那样,拖动 ...
- [UWP]如何实现UWP平台最佳图片裁剪控件
前几天我写了一个UWP图片裁剪控件ImageCropper(开源地址),自认为算是现阶段UWP社区里最好用的图片裁剪控件了,今天就来分享下我编码的过程. 为什么又要造轮子 因为开发需要,我们需要使用一 ...
- win10 uwp 绘图 Line 控件使用
本文主要讲一个在绘图中,我们会有一个基础的控件,Line.控件的基本使用和他能做出的我们很多时候需要的界面. 虽然是一个简单控件,但是可以做出很诡异的很好看的UI. 首先,我们要知道,Line就是画直 ...
- 基于PhotoView的头像/圆形裁剪控件
常见的图片裁剪有两种,一种是图片固定,裁剪框移动放缩来确定裁剪区域,早期见的比较多,缺点在于不能直接预览裁剪后的效果:还有一种现在比较普遍了,就是裁剪框固定,直接拖动缩放图片,便于预览裁剪结果. 我做 ...
- Win10系列:JavaScript 控件的使用
向页面中添加的控件可分为两种类型:标准的HTML控件和WinJS库控件.其中标准的HTML控件是指HTML标准中定义的基本控件,如按钮和复选框:WinJS库控件是为开发基于JavaScript 的Wi ...
- 在win10 + ie11上使用控件
1.1. 在Win10+IE11上提示创建文件错误的问题 解决方法: 1.打开Internet选项 2.取消勾选启用保护模式 选择"不再显示此消息"
- Win10 UI入门 圆形控件
动态模版绑定 http://blog.csdn.net/XXChen2/article/details/4552554
- 【Win10】SplitView控件
SplitView是Win10中的新控件. 用于呈现两部分视图. 一个视图是主要内容,另一个视图是用于导航.(也就是通常说的汉堡菜单.) 主要结构: <SplitView> <Spl ...
- WPF自定义控件与样式(11)-等待/忙/正在加载状态-控件实现
一.前言 申明:WPF自定义控件与样式是一个系列文章,前后是有些关联的,但大多是按照由简到繁的顺序逐步发布的等,若有不明白的地方可以参考本系列前面的文章,文末附有部分文章链接. 本文主要有三种实现方式 ...
随机推荐
- 利用php的register_shutdown_function来记录php的输出日志
最近在做的一个项目..由于全是通过远程http请求来调用php的接口程序.. 接收到的参数和返回的内容对开发人员来说都是未知不可见的.. 虽然可以通过直接在脚本中模拟请求..但由于实际环境复杂的多.. ...
- 为MongoDB创建一个Windows服务
一:选型,根据机器的操作系统类型来选择合适的版本,使用下面的命令行查询机器的操作系统版本 wmic os get osarchitecture 二:下载并安装 附上下载链接 点击安装包,我这里是把文件 ...
- poj 1442
一个排序的题目. 题意:给你m个数a[m],和n个数b[n]. 首先a[0]….a[b[0]]排序.输出第一个数. 然后a[0]….a[b[1]]排序.输出第二个数. 以此类推,直到输出第n个数. 思 ...
- android上的图片占用内存问题
近日正在把ios程序移植到android上,以前没做过android的程序,于是,想当然地把ios的图片资源放到了android工程的drawable文件夹下,这些图片都是png. 程序界面也很正常. ...
- 安装courier-authlib找不到mysqlclient.so文件
使用configure配置的时候使用 --with-authmysql指明libmysqlclient.so的存放位置即可
- 【STL】 set集合容器常用用法
set集合容器:实现了红黑树的平衡二叉检索树的数据结构,插入元素时,它会自动调整二叉树的排列,把元素放到适当的位置,以保证每个子树根节点键值大于左子树所有节点的键值,小于右子树所有节点的键值:另外,还 ...
- zookeeper windows 入门安装和测试
一.序言 以下是我对zookeeper 的一些理解: zookeeper 作为一个服务注册信息存储的管理工具,好吧,这样说得很抽象,我们举个“栗子”. 栗子1号: 假设我是一家 ...
- swift枚举
以下是指南针四个方向的一个例子: enum CompassPoint { case North case South case East case West } 多个成员值可以出现在同一行上,用 ...
- XMPP框架下微信项目总结(5)花名册获取(好友列表)
---->概念 ---->添加花名册 ps:添加花名册,启动: 客户端发送请求到服务器获取好友列表信息,同时在项目中创建数据表,并保存好友列表到数据表中. ---->获取服务器保存好 ...
- Android 图片闪烁(延迟切换)
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools=&q ...