作者: Blue_Pen
查看: 2500|回复: 0
打印 上一主题 下一主题

【窗体动画】BinGoo系列之《头像选择控件》

[复制链接]
跳转到指定楼层
楼主
Blue_Pen 发表于 2019-10-29 09:33:46 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式
查看: 2500|回复: 0
本帖最后由 Blue_Pen 于 2019-10-29 09:35 编辑

BinGoo系列之《头像选择控件》

    今天还是以DSkin的基类为基础制作一个头像选择器。

    有兴趣的可复制代码,自己重新继承重新编译,当前代码的效果图如下

   
    使用的png图片:
   

[C#] 纯文本查看 复制代码
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Imaging;
using System.Windows.Forms;
using DSkin.Common;
using DSkin.Controls;
using IDSkin.Properties;

namespace IDSkin.IControl
{
    public partial class IDSkinImageCropper : DSkinPictureBox
    {
        #region 变量
        /// <summary>
        /// 背景图像
        /// </summary>
        private Bitmap _nonepng = Resources.png;
        /// <summary>
        /// 字体
        /// </summary>
        private static readonly Font TextFont =
            new Font("Times New Roman", 12F, FontStyle.Bold, GraphicsUnit.Point, 0);
        /// <summary>
        /// 鼠标按下的焦点
        /// </summary>
        private Point _mouseDownPoint;
        /// <summary>
        /// 鼠标是否按下
        /// </summary>
        private bool _mouseDown;

        /// <summary>
        /// 选择区域的边框范围
        /// </summary>
        private Rectangle _selectImageBounds;

        /// <summary>
        /// 控件鼠标样式
        /// </summary>
        private SizeGrip _sizeGrip;

        private Rectangle _selectImageRect;
        
        #endregion

        #region 构造函数
        public IDSkinImageCropper()
        {
            InitializeComponent();
            //设置背景空图片
            this.BackgroundImage = _nonepng;
            //设置背景图片的缩放模式为平铺
            BackgroundImageLayout = ImageLayout.Tile;
            //设置图像等比例缩放
            this.SizeMode = PictureBoxSizeMode.Zoom;
        }
        #endregion

        #region 属性

        #endregion


        /// <summary>
        /// 图片选择范围
        /// 用于计算边线范围和线上小块的位置大小
        /// </summary>
        internal Rectangle SelectImageRect
        {
            get { return _selectImageRect; }
            set
            {
                _selectImageRect = value;
                if (!_selectImageRect.IsEmpty)
                {
                    CalCulateSizeGripRect();
                }
            }
        }

        /// <summary>
        /// 用于存放连线上小块的位置大小
        /// </summary>
        private Dictionary<SizeGrip, Rectangle> _sizeGripRectList = new Dictionary<SizeGrip, Rectangle>();


        private CaptureImageToolColorTable _colorTable = new CaptureImageToolColorTable();

        [Browsable(false)]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        public CaptureImageToolColorTable ColorTable
        {
            get { return _colorTable; }
            set { _colorTable = value; }
        }

        private Image _image24;
        public Image Image24
        {
            get { return _image24; }
            set
            {
                _image24 = value;
            }
        }
        private Image _image60;
        public Image Image60
        {
            get { return _image60; }
            set
            {
                _image60 = value;
            }
        }
        private Image _image100;
        public Image Image100
        {
            get { return _image100; }
            set
            {
                _image100 = value;
            }
        }

        private string _imgPath;
        private Bitmap _sourceImg;
        public Bitmap SourceImg
        {
            get { return _sourceImg; }
            set { _sourceImg = value; }
        }

        /// <summary>
        /// 设置图片路径
        /// </summary>
        public string ImgPath
        {
            get { return _imgPath; }
            set
            {
                _imgPath = value;
                if (!string.IsNullOrEmpty(_imgPath))
                {
                    SourceImg = (Bitmap)Image.FromFile(_imgPath);
                    Image img = Image.FromFile(_imgPath);
                    this.Image = img;
                    SelectImageRect = _selectImageBounds = _selectImageRect;
                    this.Invalidate();
                    GetImage();
                }
            }
        }

        DSkinPictureBox pMiddle = new DSkinPictureBox();
        public void GetImage()
        {
            try
            {
                Graphics g = pMiddle.CreateGraphics();
                Bitmap bitmap = new Bitmap(this.Image, new Size(this.Width, this.Height));
                Bitmap cloneBitmap = bitmap.Clone(_selectImageRect, PixelFormat.DontCare);
                g.DrawImage(cloneBitmap, _selectImageRect);
                SelectedImage(cloneBitmap);
            }
            catch
            {

            }
        }
        protected override void OnMouseMove(MouseEventArgs e)
        {
            base.OnMouseMove(e);
            if (_mouseDown)
            {
                ChangeSelctImageRect(e.Location);
                SetSelectRecSite();
                this.Invalidate();
            }
            else
            {
                SetSizeGrip(e.Location);
            }
        }

        protected override void OnMouseDown(MouseEventArgs e)
        {
            base.OnMouseDown(e);
            if (e.Button == MouseButtons.Left)
            {
                _mouseDown = true;
                _mouseDownPoint = e.Location;
            }
        }

        protected override void OnMouseUp(MouseEventArgs e)
        {
            base.OnMouseUp(e);
            if (e.Button == MouseButtons.Left)
                _mouseDown = false;
            GetImage();
        }

        protected override void OnLayeredPaint(PaintEventArgs e)
        {
            base.OnLayeredPaint(e);
            Graphics g = e.Graphics;
            g.SmoothingMode = SmoothingMode.HighQuality;
            Rectangle selectrect = SelectImageRect;
            CaptureImageToolColorTable colorTable = ColorTable;

            using (Pen pen = new Pen(colorTable.BorderColor))
            {
                //画外边框线条
                g.DrawRectangle(pen, selectrect);

                #region 画3*3的虚线
                pen.DashStyle = System.Drawing.Drawing2D.DashStyle.Custom;
                pen.DashPattern = new float[] { 5, 5 };
                int top = selectrect.Height / 3;
                for (int i = 1; i < 3; i++)
                {
                    g.DrawLine(pen, selectrect.X, selectrect.Y + top * i, selectrect.X + selectrect.Width, selectrect.Y + top * i);
                }
                int left = selectrect.Width / 3;
                for (int i = 1; i < 3; i++)
                {
                    g.DrawLine(pen, selectrect.X + left * i, selectrect.Y, selectrect.X + left * i, selectrect.Y + selectrect.Height);
                }
                #endregion

                #region 画外边框上的九个点
                //画外边框上的九个点
                using (SolidBrush brush = new SolidBrush(colorTable.BackColorPressed))
                {
                    foreach (Rectangle sizeGripRect in _sizeGripRectList.Values)
                    {
                        g.FillRectangle(
                            brush,
                            sizeGripRect);
                    }
                }
                #endregion
            }
            //绘制选中框以外的遮罩
            if (SelectImageRect.Width != 0 && SelectImageRect.Height != 0)
            {
                //排除选中的方形区域
                //e.Graphics.ExcludeClip(selectrect);
                //排除区域内的圆
                e.Graphics.ExcludeClip(new Region(DSkin.Common.GraphicsPathHelper.CreatePath(selectrect, selectrect.Width, RoundStyle.All, true)));
                using (SolidBrush brush = new SolidBrush(
                    Color.FromArgb(150, Color.Black)))
                {
                    Rectangle re = new Rectangle(0, 0, this.Width, this.Height);
                    g.FillRectangle(brush, re);

                }
            }
        }


        private void CalCulateSizeGripRect()
        {
            Rectangle rect = SelectImageRect;

            int x = rect.X;
            int y = rect.Y;
            int centerX = x + rect.Width / 2;
            int centerY = y + rect.Height / 2;


            Dictionary<SizeGrip, Rectangle> list = _sizeGripRectList;
            list.Clear();

            list.Add(
                SizeGrip.TopLeft,
                new Rectangle(x - 2, y - 2, 5, 5));
            list.Add(
                SizeGrip.TopRight,
                new Rectangle(rect.Right - 2, y - 2, 5, 5));
            list.Add(
                SizeGrip.BottomLeft,
                new Rectangle(x - 2, rect.Bottom - 2, 5, 5));
            list.Add(
                SizeGrip.BottomRight,
                new Rectangle(rect.Right - 2, rect.Bottom - 2, 5, 5));
            list.Add(
                SizeGrip.Top,
                new Rectangle(centerX - 2, y - 2, 5, 5));
            list.Add(
                SizeGrip.Bottom,
                new Rectangle(centerX - 2, rect.Bottom - 2, 5, 5));
            list.Add(
                SizeGrip.Left,
                new Rectangle(x - 2, centerY - 2, 5, 5));
            list.Add(
                SizeGrip.Right,
                new Rectangle(rect.Right - 2, centerY - 2, 5, 5));
        }

        //拖动选取区域的方法
        private void ChangeSelctImageRect(Point point)
        {
            Rectangle rect = _selectImageBounds;
            int left = rect.Left;
            int top = rect.Top;
            int right = rect.Right;
            int bottom = rect.Bottom;
            bool sizeGripAll = false;

            switch (_sizeGrip)
            {
                case SizeGrip.All:
                    rect.Offset(
                        point.X - _mouseDownPoint.X, point.Y - _mouseDownPoint.Y);
                    sizeGripAll = true;
                    break;
                case SizeGrip.TopLeft:
                    left = point.X;
                    top = point.Y;
                    break;
                case SizeGrip.TopRight:
                    right = point.X;
                    top = point.Y;
                    break;
                case SizeGrip.BottomLeft:
                case SizeGrip.Left:
                    left = point.X;
                    bottom = point.Y;
                    break;
                case SizeGrip.BottomRight:
                case SizeGrip.Right:
                case SizeGrip.Bottom:
                    right = point.X;
                    bottom = point.Y;
                    break;
                case SizeGrip.Top:
                    right = point.X;
                    top = point.Y;
                    break;
                    //case SizeGrip.Bottom:
                    //    bottom = point.Y;
                    //    break;
                    //case SizeGrip.Left:
                    //    left = point.X;
                    //    break;
                    //case SizeGrip.Right:
                    //    right = point.X;
                    //    break;
            }

            if (!sizeGripAll)
            {
                rect.X = left;
                rect.Y = top;
                rect.Width = right - left;
                rect.Height = bottom - top;
            }
            _mouseDownPoint = point;
            _selectImageBounds = rect;
            SelectImageRect = ImageBoundsToRect(rect);
        }
        

        private void SetSizeGrip(Point point)
        {
            _sizeGrip = SizeGrip.None;
            foreach (SizeGrip sizeGrip in _sizeGripRectList.Keys)
            {
                if (_sizeGripRectList[sizeGrip].Contains(point))
                {
                    _sizeGrip = sizeGrip;
                    break;
                }
            }

            if (_sizeGrip == SizeGrip.None)
            {
                if (SelectImageRect.Contains(point))
                {
                    _sizeGrip = SizeGrip.All;
                }
            }

            switch (_sizeGrip)
            {
                case SizeGrip.TopLeft:
                case SizeGrip.BottomRight:
                    Cursor = Cursors.SizeNWSE;
                    break;
                case SizeGrip.TopRight:
                case SizeGrip.BottomLeft:
                    Cursor = Cursors.SizeNESW;
                    break;
                case SizeGrip.Top:
                case SizeGrip.Bottom:
                    Cursor = Cursors.SizeNS;
                    break;
                case SizeGrip.Left:
                case SizeGrip.Right:
                    Cursor = Cursors.SizeWE;
                    break;
                case SizeGrip.All:
                    Cursor = Cursors.SizeAll;
                    break;
                default:
                    Cursor = Cursors.Default;
                    break;
            }
        }

        //计算画边线
        private Rectangle ImageBoundsToRect(Rectangle bounds)
        {
            Rectangle rect = bounds;
            int x = 0;
            int y = 0;

            x = Math.Min(rect.X, rect.Right);
            y = Math.Min(rect.Y, rect.Bottom);

            rect.X = x;
            rect.Y = y;

            int rWidth = 0;
            int rHeight = 0;

            rWidth = Math.Max(1, Math.Abs(rect.Width));
            rHeight = Math.Max(1, Math.Abs(rect.Height));
            rect.Width = rect.Height = Math.Max(rWidth, rHeight);

            return rect;
        }
        

        /// <summary>
        /// 控件选择区域位置
        /// </summary>
        /// <returns></returns>
        private void SetSelectRecSite()
        {
            Rectangle rect = _selectImageRect;
            bool b = false;
            if (rect.X + rect.Width > this.Width)
            {
                rect.X = this.Width - rect.Width;
                rect.Width = Math.Min(this.Width, rect.Width);
                b = true;
            }
            if (rect.Y + rect.Height > this.Height)
            {
                rect.Y = this.Height - rect.Height;
                rect.Height = Math.Min(this.Height, rect.Height);
                b = true;
            }
            if (rect.X < 0)
            {
                rect.X = 1;
                b = true;
            }
            if (rect.Y < 0)
            {
                rect.Y = 1;
                b = true;
            }
            if (b)
                SelectImageRect = _selectImageBounds = rect;
        }
        public delegate void OnSelectedImageEventHandler(Bitmap img);
        public event OnSelectedImageEventHandler OnSelectedImage;
        private void SelectedImage(Bitmap img)
        {
            if (OnSelectedImage != null)
                OnSelectedImage(img);
        }
    }
    public class CaptureImageToolColorTable
    {
        private static readonly Color _borderColor = Color.FromArgb(65, 173, 236);
        private static readonly Color _backColorNormal = Color.FromArgb(255, 255, 255);
        private static readonly Color _backColorHover = Color.FromArgb(65, 173, 236);
        private static readonly Color _backColorPressed = Color.FromArgb(24, 142, 206);
        private static readonly Color _foreColor = Color.FromArgb(12, 83, 124);

        public virtual Color BorderColor
        {
            get { return _borderColor; }
        }

        public virtual Color BackColorNormal
        {
            get { return _backColorNormal; }
        }

        public virtual Color BackColorHover
        {
            get { return _backColorHover; }
        }

        public virtual Color BackColorPressed
        {
            get { return _backColorPressed; }
        }

        public virtual Color ForeColor
        {
            get { return _foreColor; }
        }


    }

    internal enum SizeGrip
    {
        None = 0,
        Top,
        Bottom,
        Left,
        Right,
        TopLeft,
        TopRight,
        BottomLeft,
        BottomRight,
        All
    }
}



   


分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏1 转播转播
回复 论坛版权

使用道具 举报

您需要登录后才可以回帖 登录 | 加入CSkin博客

本版积分规则

QQ|申请友链|小黑屋|手机版|Archiver|CSkin ( 粤ICP备13070794号

Powered by Discuz! X3.2  © 2001-2013 Comsenz Inc.  Designed by ARTERY.cn
GMT+8, 2024-11-22 05:51, Processed in 0.508622 second(s), 33 queries , Gzip On.

快速回复 返回顶部 返回列表