利用Adorner制作用于图像裁切的选择框

简介: 原文:利用Adorner制作用于图像裁切的选择框 前天,我写了一篇“使用Adorner显示WPF控件的边界点”的文章。这次,使用从Adorner继承来写一个用于图像裁切的选择框。
原文: 利用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中已框选区域可移动,修改(比如:四周四角加方形手柄)呢? 

目录
相关文章
swiper轮播图缩略图效果彩色到黑白的变化的解决方案
swiper轮播图缩略图效果彩色到黑白的变化的解决方案
109 0
平铺文理+拉伸按钮图片
平铺文理+拉伸按钮图片
94 0
Photoshop绘制立体风格的拾色器图标
Photoshop绘制立体风格的拾色器图标
69 0
|
C# 定位技术 API
WPF技术触屏上的应用系列(四): 3D效果图片播放器(图片立体轮放、图片立体轮播、图片倒影立体滚动)效果实现
原文: WPF技术触屏上的应用系列(四): 3D效果图片播放器(图片立体轮放、图片立体轮播、图片倒影立体滚动)效果实现         去年某客户单位要做个大屏触屏应用,要对档案资源进行展示之用。
1689 0
|
C++
duilib corner属性的贴图技巧——让图片自动贴到控件的的某一边或者一角并自适应控件的大小
转载请说明原出处,谢谢~~          Duilib给控件贴图功能可以附带多个属性,各个属性的配合可以达到许多效果。以下是duilib支持的所有贴图属性: 贴图描述:          Duilib的表现力丰富很大程度上得益于贴图描述的简单强大。
1859 0
|
图形学
unity3d UGUI中底图自适应文本size
支持多行文字,底图随着文字的长度变化而自适应大小,比如游戏中常见的聊天系统,信息中都会有一个信息的底图,底图会根据文字的长宽而发生变化,例如QQ聊天也是如此的功能,unity中UGUI实现完全不需要一句代码就可以实现,具体的看下面的截图,然后自己去做一下测试就好了 测试效果.
2995 0
|
Python 容器
tkinter模块高级操作(二)—— 界面切换效果、立体阴影字效果及gif动图的实现
tkinter模块高级操作(二)—— 界面切换效果、立体阴影字效果及gif动图的实现
315 0
|
7月前
|
前端开发
Canvas绘画之多边形画板,绘制多边形,携带背景图和绘画功能,带有全部清除的功能,用这个
Canvas绘画之多边形画板,绘制多边形,携带背景图和绘画功能,带有全部清除的功能,用这个
[笔记]音视频学习之SDL篇《二》 绘制平铺的背景图并居中放置另一图片
[笔记]音视频学习之SDL篇《二》 绘制平铺的背景图并居中放置另一图片

热门文章

最新文章