利用Adorner制作用于图像裁切的选择框
前天,我写了一篇“使用Adorner显示WPF控件的边界点”的文章。这次,使用从Adorner继承来写一个用于图像裁切的选择框。
先看看效果:
C#代码:
// RubberbandAdorner.cs
#define VISUALCHILD
using System;
using System.IO;
using System.Windows;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Documents;
namespace PhotoDemo
{
#if VISUALCHILD
public class RubberbandAdorner : Adorner
{
private Window1 _window;
public Window1 Window { set { _window = value; } }
private RectangleGeometry _geometry;
private UIElement _adornedElement;
private Rect _selectRect;
public Rect SelectRect { get { return _selectRect; } }
private System.Windows.Shapes.Path _rubberband;
public System.Windows.Shapes.Path Rubberband { get { return _rubberband; } }
protected override int VisualChildrenCount { get { return 1; } }
private Point _anchorPoint;
public RubberbandAdorner(UIElement adornedElement) : base(adornedElement)
{
_adornedElement = adornedElement;
_selectRect = new Rect();
_geometry = new RectangleGeometry();
_rubberband = new System.Windows.Shapes.Path();
_rubberband.Data = _geometry;
_rubberband.StrokeThickness = 1;
_rubberband.Stroke = Brushes.Yellow;
_rubberband.Opacity = .6;
_rubberband.Visibility = Visibility.Hidden;
AddVisualChild(_rubberband);
MouseMove += new MouseEventHandler(DrawSelection);
MouseUp += new MouseButtonEventHandler(EndSelection);
}
protected override Size ArrangeOverride(Size size)
{
Size finalSize = base.ArrangeOverride(size);
((UIElement)GetVisualChild(0)).Arrange(new Rect(new Point(), finalSize));
return finalSize;
}
public void StartSelection(Point anchorPoint)
{
_anchorPoint = anchorPoint;
_selectRect.Size = new Size(10, 10);
_selectRect.Location = _anchorPoint;
_geometry.Rect = _selectRect;
if (Visibility.Visible != _rubberband.Visibility)
_rubberband.Visibility = Visibility.Visible;
}
private void DrawSelection(object sender, MouseEventArgs e)
{
if (e.LeftButton == MouseButtonState.Pressed)
{
Point mousePosition = e.GetPosition(_adornedElement);
if (mousePosition.X < _anchorPoint.X)
_selectRect.X = mousePosition.X;
else
_selectRect.X = _anchorPoint.X;
if (mousePosition.Y < _anchorPoint.Y)
_selectRect.Y = mousePosition.Y;
else
_selectRect.Y = _anchorPoint.Y;
_selectRect.Width = Math.Abs(mousePosition.X - _anchorPoint.X);
_selectRect.Height = Math.Abs(mousePosition.Y - _anchorPoint.Y);
_geometry.Rect = _selectRect;
AdornerLayer layer = AdornerLayer.GetAdornerLayer(_adornedElement);
layer.InvalidateArrange();
}
}
private void EndSelection(object sender, MouseButtonEventArgs e)
{
if (3 >= _selectRect.Width || 3 >= _selectRect.Height)
_rubberband.Visibility = Visibility.Hidden;
else
_window.CropButton.IsEnabled = true;
ReleaseMouseCapture();
}
protected override Visual GetVisualChild(int index)
{
return _rubberband;
}
}
#endif
#if NoVISUALCHILD
public class RubberbandAdorner : Adorner
{
private UIElement _adornedElement;
private bool _showRect;
private Window1 _window;
SolidColorBrush _brush;
Pen _pen;
private Rect _selectRect;
public Rect SelectRect { get { return _selectRect; } set { _selectRect = value; } }
public bool ShowRect { get { return _showRect; } set { _showRect = value; } }
public Window1 Window { set { _window = value; } }
public RubberbandAdorner(UIElement adornedElement)
: base(adornedElement)
{
_adornedElement = adornedElement;
_selectRect = new Rect();
_brush = new SolidColorBrush();
_brush.Color = Colors.Yellow;
_brush.Opacity = .6;
_pen = new Pen();
_pen.Thickness = 2;
_pen.Brush = _brush;
_showRect = false;
MouseMove += new MouseEventHandler(DrawSelection);
MouseUp += new MouseButtonEventHandler(EndSelection);
}
public void StartSelection(Point anchorPoint)
{
_anchorPoint = anchorPoint;
_selectRect.Size = new Size(0, 0);
_selectRect.Location = _anchorPoint;
if (!_showRect)
_showRect = true;
}
private void DrawSelection(object sender, MouseEventArgs e)
{
if (e.LeftButton == MouseButtonState.Pressed)
{
Point mousePosition = e.GetPosition(_adornedElement);
if (mousePosition.X < _anchorPoint.X)
_selectRect.X = mousePosition.X;
else
_selectRect.X = _anchorPoint.X;
if (mousePosition.Y < _anchorPoint.Y)
_selectRect.Y = mousePosition.Y;
else
_selectRect.Y = _anchorPoint.Y;
_selectRect.Width = Math.Abs(mousePosition.X - _anchorPoint.X);
_selectRect.Height = Math.Abs(mousePosition.Y - _anchorPoint.Y);
InvalidateArrange();
AdornerLayer layer = AdornerLayer.GetAdornerLayer(_adornedElement);
layer.InvalidateArrange();
}
}
private void EndSelection(object sender, MouseButtonEventArgs e)
{
if (3 >= _selectRect.Width || 3 >= _selectRect.Height)
ShowRect = false;
else
_window.CropButton.IsEnabled = true;
ReleaseMouseCapture();
}
protected override void OnRender(DrawingContext drawingContext)
{
if (_showRect)
{
base.OnRender(drawingContext);
drawingContext.DrawRectangle(Brushes.Transparent, _pen, _selectRect);
}
else
return;
}
}
#endif
}
目前的代码是画一个实线框,而且是静止的。
有待改进的地方:
1. 如果需要制作类似Photoshop中的“蚂蚁行军”效果呢?如何写程序呢?
2. 如果需要制作类似Photoshop中已框选区域可移动,修改(比如:四周四角加方形手柄)呢?
利用Adorner制作用于图像裁切的选择框的更多相关文章
- 类似 select 选择框效果及美化
网上有各种各样的关于 select 选择框的美化,找了很多,并没有好的样式效果.所以就找了一个利用 ul li 做的类似 select 选择框的效果,不废话了,先上图,效果如下: 对于上图的箭头效果, ...
- Spinner列表选择框
Spinner首先它是一个弹出式的列表选择框,由于间接继承了ViewGroup,所以它可以当做一个容器使用; 如果我们可以明确下拉列表中的列表项, 则可以不需要编写代码, 只需要为spinner指定a ...
- dreamweaver中的 map怎么调用?_制作热点图像区域
我们浏览网页时,经常看到一些图片上会出现特别的超链接,即在一张图片上有多个局部区域和不同的网页链接,比如地图链接. 这就是映射图像(Image Map),它是指一幅根据链接对象不同而被人为划分为若干指 ...
- 【百度地图API】如何利用PhoneGap制作地图APP
原文:[百度地图API]如何利用PhoneGap制作地图APP 摘要:百度地图API是一套由javascript编写的地图程序接口,按说它应该运行在浏览器上.现在,只要利用PhoneGap,我们就能开 ...
- 【203】利用UltraISO制作和刻录光盘映像的方法
参考:利用UltraISO制作和刻录光盘映像的方法 软件:UltraISO注册版(制作镜像).rar 目录: 1.利用UltraISO制作光盘映像2.利用UltraISO刻录光盘映像文件 1.利用Ul ...
- SIFT算法总结:用于图像搜索
原始文章链接:http://bubblexc.com/y2011/163/ 原文链接:http://blog.csdn.net/cserchen/article/details/5606859 关于三 ...
- 利用WIX制作安装包(2)
原文 利用WIX制作安装包(2) 这一篇文章将为大家介绍如何使用WIX自定义UI.上一篇文章我们讲过WIX为我们提供了五种安装界面.每种安装界面都是由不同的Dialog组成.在这里我们挑选一种比较常用 ...
- 利用pil库处理图像
1关于PIL PIL(Python Image Library)是python的第三方图像处理库,但是由于其强大的功能与众多的使用人数,几乎已经被认为是python官方图像处理库了. 2PIL的主要功 ...
- 利用Unity3D制作简易2D计算器
利用Unity3D制作简易2D计算器 标签(空格分隔): uiniy3D 1. 操作流程 在unity3DD中创建一个新项目 注意选择是2D的(因为默认3D) 在Assets框右键新建C#脚本 在新建 ...
随机推荐
- C#+AE实现类似IDentify功能及对高亮显示相关接口的总结
kenika 原文C#+AE实现类似IDentify功能及对高亮显示相关接口的总结 ArcMap中的Identify功能是有目的查看要素(Feature)属性信息经常使用的工具.ArcMap中的Ide ...
- php面试题5
php面试题5 一.总结 二.php面试题5 1. 什么事面向对象?主要特征是什么?1) 面向对象是程序的一种设计方式,它利于提高程序的重用性,是程序结构更加清晰.2) 主要特征:封装.继承.多态 2 ...
- thinkphp3.2.3 excel导出,下载文件,包含图片
关于导出后出错的问题 https://segmentfault.com/q/1010000005330214 https://blog.csdn.net/ohmygirl/article/detail ...
- 在vue中使用nprogress
NProgress的官网:http://ricostacruz.com/nprogress/ 源码地址:https://github.com/rstacruz/nprogress 1.安 ...
- [Now] Update an application hosted with Zeit’s Now
Because now deploys are immutable, you can’t push changes to a running instance - you just push a ne ...
- ios开发网络学习AFN框架的使用一:get和post请求
#import "ViewController.h" #import "AFNetworking.h" @interface ViewController () ...
- arm交叉编译Valgrind
1. wget http://valgrind.org/downloads/valgrind-3.9.0.tar.bz2 tar xvf valgrind-3.9.0.tar.bz2 cd valgr ...
- 洛谷 P1984 [SDOI2008]烧水问题
洛谷 P1984 [SDOI2008]烧水问题 题目描述 把总质量为1kg的水分装在n个杯子里,每杯水的质量均为(1/n)kg,初始温度均为0℃.现需要把每一杯水都烧开.我们可以对任意一杯水进行加热. ...
- hadoop集群安装(多机,非伪集群)
1. 创建用户 创建hadoop用户组:sudo addgroup hadoop 创建hadoop用户:sudo adduser -ingroup hadoop hadoop 为hadoop用户分配r ...
- Java IO流经典练习题(mark用)
一.练习的题目 (一) 在电脑D盘下创建一个文件为HelloWorld.txt文件,判断他是文件还是目录,在创建一个目录IOTest,之后将HelloWorld.txt移动到IOTest目录下去:之后 ...