/// <summary> /// 将颜色调暗一些 /// </summary> /// <param name="color">待修正色</param> /// <returns>修正色</returns> public static HslColor ReviseDarker(HslColor color) { return ReviseDarker(color, ReviseParameter); }
/// <summary> /// 将颜色调亮特定亮度 /// </summary> /// <param name="color">待修正色</param> /// <param name="brigher">调整的亮度</param> /// <returns>修正色</returns> public static HslColor ReviseBrighter(HslColor color, double brigher) { return new HslColor(color.Alpha, color.Hue, color.Saturation, color.Lightness + brigher); //return Color.FromRgb(ReviseByteBigger(hsvColor.R), ReviseByteBigger(hsvColor.G), ReviseByteBigger(hsvColor.B)); }
/// <summary> /// 将颜色调暗特定亮度 /// </summary> /// <param name="color">待修正色</param> /// <param name="darker">调整的亮度</param> /// <returns>修正色</returns> public static HslColor ReviseDarker(HslColor color, double darker) { return new HslColor(color.Alpha, color.Hue, color.Saturation, color.Lightness - darker); }
/// <summary> /// 将颜色调整到能够接受的最高亮度 /// </summary> /// <param name="color">待修正色</param> /// <returns>修正色</returns> public static HslColor ReviseVeryBright(HslColor color) { return ReviseBrighter(color, TooBright - color.Lightness); }
/// <summary> /// 将颜色调整到能够接受的最低亮度 /// </summary> /// <param name="color">待修正色</param> /// <returns>修正色</returns> public static HslColor ReviseVeryDark(HslColor color) { return ReviseDarker(color, color.Lightness - TooDark); }
/// <summary> /// 从图片中获取指定区域的背景颜色 /// </summary> /// <param name="pixels">The pixels.</param> /// <param name="width">The width.</param> /// <param name="height">The height.</param> /// <param name="left">The left.</param> /// <param name="right">The right.</param> /// <param name="top">The top.</param> /// <param name="bottom">The bottom.</param> /// <param name="forceDisableColorWeight">if set to <c>true</c> [force disable color weight].</param> /// <returns></returns> public static Color GetColorOfRegion(byte[] pixels, int width, int height, int left, int right, int top, int bottom, bool forceDisableColorWeight = false, bool removeFaceColor = true) { const int bytesPerPixel = 3; double sr = 0, sg = 0, sb = 0; double totalweight = 0; for (int i = top; i < bottom; i++) { for (int j = left; j < right; j++) { byte r = pixels[(i * width + j) * bytesPerPixel + 0]; byte g = pixels[(i * width + j) * bytesPerPixel + 1]; byte b = pixels[(i * width + j) * bytesPerPixel + 2]; double weight; if (!forceDisableColorWeight && EnableColorWeight) { var color = Color.FromRgb(r, g, b); var hslColor = new HslColor(color); weight = (1 - Math.Abs(1 - 2*hslColor.Lightness))*hslColor.Saturation; if (weight < MinWeight) { weight = 0; } if (removeFaceColor) { var difference = Math.Abs(new HslColor(FaceColor).Hue - hslColor.Hue)/360; if (difference <= ZeroWeightFaceColorDifference) { weight = 0; } else { weight = weight*difference; } } } else { weight = 1; } totalweight += weight; sr += r * weight; sg += g * weight; sb += b * weight; } } if (totalweight <= 0) { if (removeFaceColor) { //当去除人脸色彩后总权重为0时,禁用去除人脸色彩 return GetColorOfRegion(pixels, width, height, left, right, top, bottom, false, false); } else { //纯灰度图片不能使用权重 var newColor = GetColorOfRegion(pixels, width, height, left, right, top, bottom, true); var newHslColor = new HslColor(newColor); newHslColor.Saturation = 0; return newHslColor.ToRgb(); } } else { sr = sr/totalweight; sg = sg/totalweight; sb = sb/totalweight; return Color.FromRgb((byte) sr, (byte) sg, (byte) sb); } }
/// <summary> /// 无参照色时的颜色修正 /// </summary> /// <param name="color">待修正色</param> /// <returns>修正色</returns> public static HslColor Revise(HslColor color) { if (IsTooDark(color)) return ReviseBrighter(color); if (IsTooBright(color)) return ReviseVeryBright(color); //color = ReviseDarker(color); //if (IsTooDark(color)) //return ReviseVeryDark(color); return color; }
/// <summary> /// 颜色是否太亮 /// </summary> /// <param name="color">颜色</param> /// <returns>Boolean值</returns> public static bool IsTooBright(HslColor color) { return color.Lightness > TooBright; }
/// <summary> /// 反色 /// </summary> /// <param name="color">原色</param> /// <returns>反色</returns> public static HslColor Reverse(HslColor color) { Color rgb = color.ToRgb(); return new HslColor(Color.FromArgb(rgb.A, (byte)(255 - rgb.R), (byte)(255 - rgb.G), (byte)(255 - rgb.B))); //return new HSLColor(hsvColor.Alpha, hsvColor.Hue + 180, 1 - hsvColor.Saturation, 1 - hsvColor.Lightness); }
/// <summary> /// 颜色饱和度是否接近0 /// </summary> /// <param name="color">颜色</param> /// <returns>Boolean值</returns> public static bool IsAlmostZeroSaturation(HslColor color) { return color.Saturation < AlmostZeroSaturation; }
/// <summary> /// 颜色是否太暗 /// </summary> /// <param name="color">颜色</param> /// <returns>Boolean值</returns> public static bool IsTooDark(HslColor color) { return color.Lightness < TooDark; }
/// <summary> /// 颜色饱和度是否太低 /// </summary> /// <param name="color">颜色</param> /// <returns>Boolean值</returns> public static bool IsNotSaturateEnough(HslColor color) { return color.Saturation < NotSaturateEnough; }
/// <summary> /// 计算两种颜色的差异。0为无差异,1为差异最大值 /// </summary> /// <param name="c1">颜色1</param> /// <param name="c2">颜色2</param> /// <returns>差异值</returns> public static double Difference(HslColor c1, HslColor c2) { return Difference(c1.ToRgb(), c2.ToRgb()); }
/// <summary> /// 两种颜色差异是否足够大 /// </summary> /// <param name="c1">颜色1</param> /// <param name="c2">颜色2</param> /// <returns>Boolean值</returns> public static bool IsTooMuchDiff(HslColor c1, HslColor c2) { return Difference(c1, c2) > CoverColorDiff; //return Math.Abs((c1.R - c2.R) * (c1.R - c2.R) + (c1.G - c2.G) * (c1.G - c2.G) + (c1.B - c2.B) * (c1.B - c2.B)) > CoverColorDiff; }
/// <summary> /// 转换到RGB色彩空间 /// </summary> /// <param name="hsl">HSL颜色</param> /// <returns>转换后的RGB颜色</returns> public static Color ToRgb(HslColor hsl) { byte a = (byte)Math.Round(hsl.Alpha * 255), r, g, b; if (hsl.Saturation == 0) { r = (byte)Math.Round(hsl.Lightness * 255); g = r; b = r; } else { double vH = hsl.Hue / 360; double v2 = hsl.Lightness < 0.5 ? hsl.Lightness * (1 + hsl.Saturation) : (hsl.Lightness + hsl.Saturation) - (hsl.Lightness * hsl.Saturation); double v1 = 2 * hsl.Lightness - v2; r = (byte)Math.Round(255 * HueToRgb(v1, v2, vH + 1.0 / 3)); g = (byte)Math.Round(255 * HueToRgb(v1, v2, vH)); b = (byte)Math.Round(255 * HueToRgb(v1, v2, vH - 1.0 / 3)); } return Color.FromArgb(a, r, g, b); }
/// <summary> /// 颜色修正 /// </summary> /// <param name="color1">待修正色</param> /// <param name="color2">参照色</param> /// <returns>修正色</returns> public static HslColor Revise(HslColor color1, HslColor color2) { var newcolor = new HslColor(color1.ToRgb()); while (IsTooBright(newcolor) || !IsTooMuchDiff(newcolor, color2) && !IsTooDark(newcolor) && newcolor.Lightness > 0) newcolor = ReviseDarker(newcolor); if (!IsTooDark(newcolor)) return newcolor; newcolor = ReviseBrighter(color1); while (IsTooDark(newcolor) || !IsTooMuchDiff(newcolor, color2) && !IsTooBright(newcolor) && newcolor.Lightness < 1) newcolor = ReviseBrighter(newcolor); if (!IsTooBright(newcolor)) return newcolor; if (IsTooBright(color1)) return ReviseVeryBright(color1); if (IsTooDark(color1)) return ReviseVeryDark(color1); return color1; }
/// <summary> /// 由窗口背景转换为桌面歌词前景 /// </summary> public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) { if (value is SolidColorBrush) { HslColor color = new HslColor(((SolidColorBrush)value).Color); color.Alpha = 1.0; if (color.Lightness < 0.7) color.Lightness = 0.7; SolidColorBrush brush = new SolidColorBrush(color.ToRgb()); if (brush.CanFreeze) brush.Freeze(); return brush; } return value; }
/// <summary> /// 从图片中获取背景颜色 /// </summary> /// <param name="bitmap">图片</param> public static Color GetImageColorForBackground(FormatConvertedBitmap bitmap) { const int bytesPerPixel = 3; if (bitmap.CanFreeze) bitmap.Freeze(); var pixels = new byte[bitmap.PixelHeight * bitmap.PixelWidth * bytesPerPixel]; bitmap.CopyPixels(pixels, bitmap.PixelWidth * bytesPerPixel, 0); var width = bitmap.PixelWidth; var height = bitmap.PixelHeight; //计算颜色的均值 Color color = GetColorOfRegion(pixels, width, height, 0, width, 0, height); var hsl = new HslColor(color); if (IsNotSaturateEnough(hsl) && !IsAlmostZeroSaturation(hsl)) hsl.Saturation += 0.2; return Revise(hsl).ToRgb(); }