// *********************************************************************** // Assembly : HZH_Controls // Created : 2019-09-28 // // *********************************************************************** // // Copyright by Huang Zhenghui(黄正辉) All, QQ group:568015492 QQ:623128629 Email:623128629@qq.com // // // Blog: https://www.cnblogs.com/bfyx // GitHub:https://github.com/kwwwvagaa/NetWinformControl // gitee:https://gitee.com/kwwwvagaa/net_winform_custom_control.git // // If you use this code, please keep this note. // *********************************************************************** 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 { /// /// Class UCSampling. /// Implements the /// /// public class UCSampling : UserControl { /// /// The sampling imag /// private Bitmap samplingImag = null; /// /// Gets or sets the sampling imag. /// /// The sampling imag. [Browsable(true), Category("自定义属性"), Description("采样图片"), Localizable(true)] public Bitmap SamplingImag { get { return samplingImag; } set { samplingImag = value; ResetBorderPath(); Invalidate(); } } /// /// The transparent /// private Color? transparent = null; /// /// Gets or sets the transparent. /// /// The transparent. [Browsable(true), Category("自定义属性"), Description("透明色,如果为空,则使用0,0坐标处的颜色"), Localizable(true)] public Color? Transparent { get { return transparent; } set { transparent = value; ResetBorderPath(); Invalidate(); } } /// /// The alpha /// private int alpha = 50; /// /// Gets or sets the alpha. /// /// The alpha. [Browsable(true), Category("自定义属性"), Description("当作透明色的透明度,小于此透明度的颜色将被认定为透明,0-255"), Localizable(true)] public int Alpha { get { return alpha; } set { if (value < 0 || value > 255) return; alpha = value; ResetBorderPath(); Invalidate(); } } /// /// The color threshold /// private int colorThreshold = 10; /// /// Gets or sets the color threshold. /// /// The color threshold. [Browsable(true), Category("自定义属性"), Description("透明色颜色阀值"), Localizable(true)] public int ColorThreshold { get { return colorThreshold; } set { colorThreshold = value; ResetBorderPath(); Invalidate(); } } /// /// The bit cache /// private Bitmap _bitCache; /// /// Initializes a new instance of the class. /// public UCSampling() { 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); } /// /// The m border path /// GraphicsPath m_borderPath = new GraphicsPath(); /// /// Handles the SizeChanged event of the UCSampling control. /// /// The source of the event. /// The instance containing the event data. void UCSampling_SizeChanged(object sender, EventArgs e) { ResetBorderPath(); } /// /// Resets the border path. /// 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 lstPoints = GetBorderPoints(bit, transparent ?? samplingImag.GetPixel(0, 0)); m_borderPath.AddLines(lstPoints.ToArray()); m_borderPath.CloseAllFigures(); } } /// /// Gets the border points. /// /// The bit. /// The transparent. /// List<PointF>. private List 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 lstPoint = new List(); 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; } /// /// Determines whether [is like color] [the specified color1]. /// /// The color1. /// The color2. /// true if [is like color] [the specified color1]; otherwise, false. private bool IsLikeColor(Color color1, Color color2) { var 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 根据角度得到坐标 English:Get coordinates from angles /// /// 功能描述:根据角度得到坐标 English:Get coordinates from angles /// 作  者:HZH /// 创建日期:2019-09-28 11:56:25 /// 任务编号:POS /// /// angle /// radius /// origin /// 返回值 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); } } }