• 颜色扩展类--ColorExtensions


    /// <summary>
    /// 颜色扩展类
    /// </summary>
    public static class ColorExtensions
    {
        /// <summary>
        /// .NET预定义的系统颜色缓存列表
        /// </summary>
        private static readonly Dictionary<int, Color> ColorCache;
    
        /// <summary>
        /// 拥有相同颜色代码值的系统颜色名称列表
        /// </summary>
        private static readonly Dictionary<int, string[]> DuplicateColorNameCache;
        
        /// <summary>
        /// 静态构造函数
        /// </summary>
        static ColorExtensions()
        {
            ColorCache = new Dictionary<int, Color>();
            DuplicateColorNameCache = new Dictionary<int, string[]>();
            
            Type type = typeof(Color);
            var properties = type.GetProperties(BindingFlags.Public | BindingFlags.Static | BindingFlags.IgnoreCase);
            foreach (var propertyInfo in properties)
            {
                var value = propertyInfo.GetValue(null, null);
                if (value is Color)
                {
                    var color = (Color) value;
                    var intCode = color.ToIntCode();
                    if (!ColorCache.ContainsKey(intCode))
                    {
                        ColorCache.Add(intCode, color);
                    }
                    else
                    {
                        if (DuplicateColorNameCache.ContainsKey(intCode))
                        {
                            var values = DuplicateColorNameCache[intCode].ToList();
                            values.Add(color.Name);
                            DuplicateColorNameCache[intCode] = values.ToArray();
                        }
                        else
                        {
                            string[] values = { ColorCache[intCode].Name, color.Name };
                            DuplicateColorNameCache[intCode] = values;
                        }
                    }
                }
            }
        }
    
        /// <summary>
        /// 返回用十进制格式的颜色值,该值范围在0~16777215。
        /// <para>例:0表示黑色,16777215表示白色。</para>
        /// </summary>
        /// <param name="color">Color对象</param>
        /// <returns>十进制格式的颜色值</returns>
        public static int ToIntCode(this Color color)
        {
            int c = color.R;
            c = c | color.G << 8;
            c = c | color.B << 16;
    
            return c;
            
            //以下代码等效
            //先转成16进制值,再转成10进制值
            //var hexCode = color.ToHexCode(false);//获取十六进制格式的颜色代码值
            //int intCode = Convert.ToInt32(hexCode, 16);//获取十进制格式的颜色代码值
        }
    
        /// <summary>
        /// 返回十六进制格式的颜色值。
        /// <para>例:Color.Gray(灰色)返回#808080。Color.FromArgb(192,192,192) 返回#C0C0C0</para>
        /// </summary>
        /// <param name="color">Color对象</param>
        /// <param name="isAddPrefix">是否添加前缀"#", 默认为 true。</param>
        /// <returns>十六进制格式的颜色值</returns>
        public static string ToHexCode(this Color color, bool isAddPrefix = true)
        {
            return string.Format("{0}{1:X2}{2:X2}{3:X2}", isAddPrefix ? "#" : string.Empty, color.R, color.G, color.B);
            
            //下面这个方法,遇到.NET预定义的颜色对象,会返回颜色名称,而不是十六进制值。
            //return ColorTranslator.ToHtml(color);
        }
    
        /// <summary>
        /// 返回HTML支持的颜色代码值,如果颜色已在HTML预定义,则返回颜色名称,否则返回十六进制格式表示的代码值。
        /// <para>例:Color.Gray(灰色)返回Gray。Color.FromArgb(192,192,192) 返回#C0C0C0(银白色)</para>
        /// <para>例:这是因为HTML中已预定义该颜色代码值,所以HTML支持该颜色代码值所对应的名称值。</para>
        /// <para>.NET有三对预定义颜色的代码值是相同的,所以当传入以ARGB表示的颜色对象刚好在这三对预定义颜色范围,那么只会返回一对中的其中一个颜色名称。</para>
        /// <para>当你需要知道另外一个颜色名称,你可以通过</para>
        /// </summary>
        /// <param name="color">Color对象</param>
        /// <returns>如果颜色已在HTML预定义,则返回颜色的友好名称,否则返回十六进制格式表示的代码值</returns>
        public static string ToHtmlCode(this Color color)
        {
            int intCode = color.ToIntCode();
            if (ColorCache.ContainsKey(intCode))
            {
                return ColorTranslator.ToHtml(ColorCache[intCode]);
            }
            /*
             * 上面之所以要这样做,是因为当使用者传过来一个使用ARGB表示的Color对象。
             * 经过以上处理后,下面可以顺利返回颜色的名称。
             * 例: Color color1 = Color.Gray; //灰色
             *      Color color2 = Color.FromArgb(color1.A, color1.R, color1.G, color1.B);
             *      color1.ToHtmlCode() 返回"Gray"
             *      color2.ToHtmlCode() 返回"#808080".
             * 其实以上两个Color对象是相等的,这两个对象调用ToHtmlCode()扩展方法都应该返回同一个结果才是比较合理的。
             */
            return ColorTranslator.ToHtml(color);
        }
    
        /// <summary>
        /// 获取具有相同代码值的颜色名称数组,如果没有,则返回null。
        /// </summary>
        /// <param name="color">Color对象</param>
        /// <returns>返回具有相同代码值的颜色名称数组,如果没有,则返回null。</returns>
        public static string[] GetDuplicateColorNames(this Color color)
        {
            int intCode = color.ToIntCode();
            if (DuplicateColorNameCache.ContainsKey(intCode))
            {
                return DuplicateColorNameCache[intCode];
            }
    
            return null;
        }
    
        /// <summary>
        /// 转换十进制格式的颜色代码值为Color对象
        /// </summary>
        /// <param name="intCode">十进制格式的颜色代码值</param>
        /// <returns>返回Color对象</returns>
        public static Color IntToColor(int intCode)
        {
            if (ColorCache.ContainsKey(intCode))
            {
                return ColorCache[intCode];
            }
            /*
             * 以上处理与ToHtmlCode方法同理
             * 先检查是否与.NET预定义的颜色匹配,如果匹配,返回.NET预定义的颜色对象(该对象包含一个可被直接理解的颜色友好名称)。
             * 如果不匹配,则返回用ARGB表示的Color对象。
             */
            string hexCode = Convert.ToString(intCode, 16);
            return ColorTranslator.FromHtml("#" + hexCode);
        }
    
        /// <summary>
        /// 转换以"#"开头的六位长度的十六进制格式的颜色代码值或.NET预定义的颜色名称为Color对象
        /// </summary>
        /// <param name="hexCodeOrColorName">.NET预定义的颜色名称或以"#"开头的6位长度的十六进制颜色代码值</param>
        /// <returns></returns>
        public static Color HexOrNameToColor(string hexCodeOrColorName)
        {
            if (string.IsNullOrEmpty(hexCodeOrColorName))
            {
                return Color.Empty;
            }
    
            try
            {
                //This is hex code.
                if (hexCodeOrColorName[0] == '#')
                {
                    string hexCode = hexCodeOrColorName.Substring(1);
                    int intCode = Convert.ToInt32(hexCode, 16);
                    if (ColorCache.ContainsKey(intCode))
                    {
                        //返回拥有友好名称的Color对象
                        return ColorCache[intCode];
                    }
    
                    //返回以ARGB表示的Color对象
                    return ColorTranslator.FromHtml(hexCodeOrColorName);
                }
    
                //This is color name.
                return ColorTranslator.FromHtml(hexCodeOrColorName);
            }
            catch (Exception)
            {
                return Color.Empty;
            }
        }
    }
  • 相关阅读:
    请为新诗赐题
    ***套接字连接已中止。这可能是由于处理消息时出错或远程主机超过接收超时或者潜在的网络资源问题导致的
    关于sum(int)报错:将expression转化为数据类型int时发生算术溢出错误
    【SSB】清空service broker中的队列
    【SSB 】Handling and Removing Poison Messages
    一淘网的系统架构
    WCF服务器已拒绝客户端凭据
    Web 安全威胁与对策
    SQL Prompt 4 破解步骤
    【SSB】Activation Execution Context
  • 原文地址:https://www.cnblogs.com/VAllen/p/ColorExtensions.html
Copyright © 2020-2023  润新知