yangyin
2025-02-28 baa80d650adebcce70f1113cc1020c6039c159a0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Windows.Forms;
namespace DPumpHydr.WinFrmUI.WenSkin.Controls
{
    public class UControl : Control
    {
        public UControl()
        {
            SetStyle(ControlStyles.AllPaintingInWmPaint, true);
            SetStyle(ControlStyles.DoubleBuffer, true);
            SetStyle(ControlStyles.ResizeRedraw, true);
            SetStyle(ControlStyles.Selectable, true);
            SetStyle(ControlStyles.SupportsTransparentBackColor, true);
            SetStyle(ControlStyles.UserPaint, true);
            SizeChanged += UCSampling_SizeChanged;
            Size = new Size(35, 35);
        }
 
        GraphicsPath m_borderPath = new GraphicsPath();
 
        #region 私有属性
        private Bitmap samplingImag = null;
        private Color transparent = Color.White;
        private int alpha = 50;
        private int colorThreshold = 10;
        private Bitmap _bitCache;
        #endregion
 
        #region 公有属性
 
        [Browsable(true), Category("Wen"), Description("采样图片"), Localizable(true)]
        public Bitmap SamplingImag
        {
            get { return samplingImag; }
            set
            {
                samplingImag = value;
                ResetBorderPath();
                Invalidate();
            }
        }
        [Browsable(true), Category("Wen"), Description("透明色"), Localizable(true)]
        public Color Transparent
        {
            get { return transparent; }
            set
            {
                transparent = value;
                ResetBorderPath();
                Invalidate();
            }
        }
        [Browsable(true), Category("Wen"), Description("当作透明色的透明度,小于此透明度的颜色将被认定为透明,0-255"), Localizable(true)]
        public int Alpha
        {
            get { return alpha; }
            set
            {
                if (value < 0 || value > 255)
                    return;
                alpha = value;
                ResetBorderPath();
                Invalidate();
            }
        }
        [Browsable(true), Category("Wen"), Description("透明色颜色阀值"), Localizable(true)]
        public int ColorThreshold
        {
            get { return colorThreshold; }
            set
            {
                colorThreshold = value;
                ResetBorderPath();
                Invalidate();
            }
        }
 
        #endregion
 
        void UCSampling_SizeChanged(object sender, EventArgs e)
        {
            ResetBorderPath();
        }
 
        private void ResetBorderPath()
        {
            if (samplingImag == null)
            {
                m_borderPath = ClientRectangle.CreateRoundedRectanglePath(5);
            }
            else
            {
                var bit = new Bitmap(ClientRectangle.Width, ClientRectangle.Height);
                using (var bitg = Graphics.FromImage(bit))
                {
                    bitg.DrawImage(samplingImag, ClientRectangle, 0, 0, samplingImag.Width, samplingImag.Height, GraphicsUnit.Pixel);
                }
                _bitCache = bit;
                m_borderPath = new GraphicsPath();
                List<PointF> lstPoints = GetBorderPoints(bit, transparent);
                m_borderPath.AddLines(lstPoints.ToArray());
                m_borderPath.CloseAllFigures();
            }
        }
 
        private List<PointF> GetBorderPoints(Bitmap bit, Color transparent)
        {
            float diameter = (float)Math.Sqrt(bit.Width * bit.Width + bit.Height * bit.Height);
            int intSplit = (int)(7 - (diameter - 200) / 100);
            if (intSplit < 1)
                intSplit = 1;
            List<PointF> lstPoint = new List<PointF>();
            for (int i = 0; i < 360; i += intSplit)
            {
                for (int j = (int)diameter / 2; j > 5; j--)
                {
                    Point p = GetPointByAngle(i, j, new PointF(bit.Width / 2, bit.Height / 2));
                    if (p.X < 0 || p.Y < 0 || p.X >= bit.Width || p.Y >= bit.Height)
                        continue;
                    Color _color = bit.GetPixel(p.X, p.Y);
                    if (!(_color.A <= alpha || IsLikeColor(_color, transparent)))
                    {
                        if (!lstPoint.Contains(p))
                        {
                            lstPoint.Add(p);
                        }
                        break;
                    }
                }
            }
            return lstPoint;
        }
 
        private bool IsLikeColor(Color color1, Color color2)
        {
            double cv = Math.Sqrt(Math.Pow(color1.R - color2.R, 2) + Math.Pow(color1.G - color2.G, 2) + Math.Pow(color1.B - color2.B, 2));
            if (cv <= colorThreshold)
                return true;
            else
                return false;
        }
 
        #region 根据角度得到坐标
        /// <summary>
        /// 功能描述:根据角度得到坐标 
        /// </summary>
        private Point GetPointByAngle(float angle, float radius, PointF origin)
        {
            float y = origin.Y + (float)Math.Sin(Math.PI * (angle / 180.00F)) * radius;
            float x = origin.X + (float)Math.Cos(Math.PI * (angle / 180.00F)) * radius;
            return new Point((int)x, (int)y);
        }
        #endregion
 
        protected override void OnPaint(PaintEventArgs e)
        {
            base.OnPaint(e);
            e.Graphics.SetGDIHigh();
 
            Region = new Region(m_borderPath);
 
            if (_bitCache != null)
                e.Graphics.DrawImage(_bitCache, 0, 0);
        }
    }
}