原文:利用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制作用于图像裁切的选择框相关推荐

  1. 制作用于图像语义分割训练的标签数据【图像分割】【labelme】

    制作用于图像语义分割训练的标签数据 *写在前面 一.使用labelme制作json数据 1.安装labelme 2.利用labelme制作json数据 二.将json数据转化为图像数据 1.单个jso ...

  2. js中select下拉框重置_如何利用CSS3制作炫酷的下拉框

    很多小伙伴都不清楚CSS3是做什么?用途是什么? 接下来我就给展示一个css3制作一个炫酷下拉框.其实不只是这些,还有很多. CSS3是CSS(层叠样式表)技术的升级版本,于1999年开始制订,200 ...

  3. wps中制作自动打勾的选择框

    在WPS中,可以在"开发工具"中,选择复选框后,点控件属性: 在复选框属性中,点"选中标记",点"更改", 然后字体选wingwing2,就 ...

  4. 设置matlab图像线框,matlab在图像中画长方形(框)

    function [state,result]=draw_rect(data,pointAll,windSize,showOrNot) % 函数调用:[state,result]=draw_rect( ...

  5. 用计算机绘制函数图像ppt,如何利用描点画函数图像课件制作

    原标题:如何利用描点画函数图像课件制作 函数是中学数学中的一个重要内容,而描点画图不仅是学生在课堂上学习函数的重要方法,也是学生在今后学习课本外其他函数的重要途径.下面介绍描点画函数图像课件制作方法, ...

  6. 抖音上的c语言动态爱心代码,教程:利用Excel 制作 抖音上的心形动态函数图像 ,可以用来表白哈...

    本帖最后由 一笑倾城雪 于 2019-1-5 22:39 编辑 今天在抖音上看到一个抖友,发了一个短视频.视频中利用Excel制作出一个漂亮,并通过动态赋值,实现心形变化的函数图(如下图). 觉得十分 ...

  7. 动态给a标签赋值_怎样利用Excel制作抖音上的心形动态函数图像?

    最近在抖音上看到有用Excel制作心形动态函数图像,感觉很新奇,闲来无事,准备自己动手做做,遂网上搜了教程,按照教程一步步做,前面都很顺利,但到最后一部确卡壳,问了公司Excel大牛也未找到原因,知道 ...

  8. 利用PS制作图像处理中的模板(掩膜)

    1. 背景 写这篇文字的原因是当时需要制作一个掩膜,但是在网上搜了一圈,没有特别满意的答案,导致自己多花了一点时间,希望这篇文章能让ps小白快速地制作出一个用于图像预处理的掩膜. 先来介绍一下环境 操 ...

  9. 视觉进阶 | 用于图像降噪的卷积自编码器

    点击上方"小白学视觉",选择加"星标"或"置顶" 重磅干货,第一时间送达 本文转自:磐创AI 作者|Dataman 编译|Arno 来源|A ...

最新文章

  1. jfinal js 拦截_jfinal 使用拦截器处理繁琐的前置条件判定
  2. vue状态管理存取数据_vue状态管理vuex从浅入深详细讲解
  3. Nginx的可视化神器nginx-gui的下载配置和使用
  4. OpenCV学习笔记(十四):重映射:remap( )
  5. vscode如何连接新设备_台州要用“超级平台”连接300万台工业设备,成为全省新示范...
  6. hydra安装及使用
  7. 吴恩达机器学习之单变量线性回归理论部分
  8. php 遍历数组 只显示1个,求高手指点,foreach遍历三维数组时只能遍历出第一个子级,这是为什么呢?...
  9. 自主品牌语音交互性能测评,荣威RX5反应更快,博越变暖男
  10. Ubuntu 下 MySQL 数据自执行备份
  11. day16——oracle灾备2
  12. AOP结构图(术语图解)
  13. mysql PT工具
  14. Windows系統修改MAC地址的方法
  15. 织梦dedecms 模板代码标签学习
  16. pythonlauncher是干什么用的_python launcher是什么
  17. Photoshop cs5 永久序列号
  18. 电商小程序实战教程-分类导航
  19. 十大炒股杠杆平台到底有哪些交易模式?
  20. linux设备驱动读书笔记

热门文章

  1. Jenkins插件开发(四)-- 插件发布
  2. 【python】Python的基本数据类型之数字类型与字符串类型
  3. 一图总结:软件测试原则|策略|模型|生命周期
  4. mysql sql注入怎么获取数据_手把手教你通过SQL注入盗取数据库信息
  5. winfrom 如何让弹窗不影响主界面_「Win」电脑开机后不给我弹几个广告,我还不太习惯...
  6. 如何能成为一名合格的前端开发工程师?
  7. linux mint安装类型,如何在Linux Mint 16中正确安装Ubuntu One
  8. 中专计算机应用完整教学计划,中职生教学计划
  9. android 蓝牙与单片机通信原理图,手机蓝牙与HC-06蓝牙模块控制单片机程序加APP...
  10. python 制作简单网站_新手小白 做python爬虫 爬什么网站比较简单?