Example #1
0
		/// <summary>
		/// 从图片中获取背景颜色
		/// </summary>
		/// <param name="image">图片</param>
		/// <param name="callback">计算完成后调用的委托</param>
		public static void GetImageColorForBackgroundAsync(BitmapSource image, ComputeCompleteCallback callback)
		{
			FormatConvertedBitmap bitmap = null;
			const int bytesPerPixel = 3;
			byte[] pixels = null;
			int width = 0;
			int height = 0;
			bool isFrozen = image.IsFrozen;
			if (!isFrozen)
			{
				//由于image没有冻结,所以image不能跨线程使用,这时要在当前线程中将image转换为另一个位图
				bitmap = new FormatConvertedBitmap(image, PixelFormats.Rgb24, BitmapPalettes.WebPalette, 0);
				if (bitmap.CanFreeze) bitmap.Freeze();
				pixels = new byte[bitmap.PixelHeight * bitmap.PixelWidth * bytesPerPixel];
				bitmap.CopyPixels(pixels, bitmap.PixelWidth * bytesPerPixel, 0);
				width = bitmap.PixelWidth;
				height = bitmap.PixelHeight;
			}
			ThreadPool.QueueUserWorkItem(new WaitCallback((state) =>
				{
					if (isFrozen)
					{
						//由于image已经冻结,所以image可以跨线程使用,这时在新线程中将image转换为另一个位图
						bitmap = new FormatConvertedBitmap(image, PixelFormats.Rgb24, BitmapPalettes.WebPalette, 0);
						if (bitmap.CanFreeze) bitmap.Freeze();
						pixels = new byte[bitmap.PixelHeight * bitmap.PixelWidth * bytesPerPixel];
						bitmap.CopyPixels(pixels, bitmap.PixelWidth * bytesPerPixel, 0);
						width = bitmap.PixelWidth;
						height = bitmap.PixelHeight;
					}

					//计算颜色的均值
					int sum = width * height;
					int r = 0, g = 0, b = 0;
					int offset = 0;
					for (int i = 0; i < height; i++)
					{
						for (int j = 0; j < width; j++)
						{
							r += pixels[offset++];
							g += pixels[offset++];
							b += pixels[offset++];
						}
					}
					r = r / sum;
					g = g / sum;
					b = b / sum;
					Color color1 = Color.FromRgb((byte)r, (byte)g, (byte)b);

					//计算图片右部的颜色均值
					r = 0; g = 0; b = 0;
					int jstart = (int)(width * (1 - RightSideWidth));
					sum = (width - jstart) * width;
					for (int i = 0; i < height; i++)
					{
						for (int j = jstart; j < width; j++)
						{
							r += pixels[(i * width + j) * bytesPerPixel + 0];
							g += pixels[(i * width + j) * bytesPerPixel + 1];
							b += pixels[(i * width + j) * bytesPerPixel + 2];
						}
					}
					r = r / sum;
					g = g / sum;
					b = b / sum;
					Color color2 = Color.FromRgb((byte)r, (byte)g, (byte)b);

					//根据上面计算出来的两个颜色计算最终颜色
					HSLColor hsl1 = new HSLColor(color1);
					HSLColor hsl2 = new HSLColor(color2);
					hsl1.Hue += 10;
					if (IsNotSaturateEnough(hsl1) && !IsAlmostZeroSaturation(hsl1))
						hsl1.Saturation += 0.2;
					callback(Revise(hsl1, hsl2).ToRGB());
				}));
		}
Example #2
0
		/// <summary>
		/// 将颜色调暗一些
		/// </summary>
		/// <param name="hsvColor">待修正色</param>
		/// <returns>修正色</returns>
		public static HSLColor ReviseDarker(HSLColor color)
		{
			return ReviseDarker(color, ReviseParameter);
		}
Example #3
0
		/// <summary>
		/// 转换到RGB色彩空间
		/// </summary>
		/// <param name="hsl">HSL颜色</param>
		/// <returns>转换后的RGB颜色</returns>
		private 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);
		}
Example #4
0
		/// <summary>
		/// 将颜色调亮特定亮度
		/// </summary>
		/// <param name="hsvColor">待修正色</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));
		}
Example #5
0
		/// <summary>
		/// 将颜色调暗特定亮度
		/// </summary>
		/// <param name="hsvColor">待修正色</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);
		}
Example #6
0
		/// <summary>
		/// 将颜色调整到能够接受的最高亮度
		/// </summary>
		/// <param name="hsvColor">待修正色</param>
		/// <returns>修正色</returns>
		public static HSLColor ReviseVeryBright(HSLColor color)
		{
			return ReviseBrighter(color, TooBright - color.Lightness);
		}
Example #7
0
		/// <summary>
		/// 将颜色调整到能够接受的最低亮度
		/// </summary>
		/// <param name="hsvColor">待修正色</param>
		/// <returns>修正色</returns>
		public static HSLColor ReviseVeryDark(HSLColor color)
		{
			return ReviseDarker(color, color.Lightness - TooDark);
		}
Example #8
0
		/// <summary>
		/// 颜色修正
		/// </summary>
		/// <param name="color1">待修正色</param>
		/// <param name="color2">参照色</param>
		/// <returns>修正色</returns>
		public static HSLColor Revise(HSLColor color1, HSLColor color2)
		{
			HSLColor 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;

		}
Example #9
0
		/// <summary>
		/// 无参照色时的颜色修正
		/// </summary>
		/// <param name="hsvColor">待修正色</param>
		/// <returns>修正色</returns>
		public static HSLColor Revise(HSLColor color)
		{
			if (IsTooDark(color))
				return ReviseBrighter(color);
			else
			{
				HSLColor newcolor = ReviseDarker(color);
				if (IsTooDark(newcolor))
					return ReviseVeryDark(color);
				else
					return newcolor;
			}
		}
Example #10
0
		/// <summary>
		/// 颜色是否太亮
		/// </summary>
		/// <param name="hsvColor">颜色</param>
		/// <returns>Boolean值</returns>
		public static bool IsTooBright(HSLColor color)
		{
			return color.Lightness > TooBright;
		}
Example #11
0
		/// <summary>
		/// 反色
		/// </summary>
		/// <param name="hsvColor">原色</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);
		}
Example #12
0
		/// <summary>
		/// 颜色是否太暗
		/// </summary>
		/// <param name="hsvColor">颜色</param>
		/// <returns>Boolean值</returns>
		public static bool IsTooDark(HSLColor color)
		{
			return color.Lightness < TooDark;
		}
Example #13
0
		/// <summary>
		/// 颜色饱和度是否接近0
		/// </summary>
		/// <param name="hsvColor">颜色</param>
		/// <returns>Boolean值</returns>
		public static bool IsAlmostZeroSaturation(HSLColor color)
		{
			return color.Saturation < AlmostZeroSaturation;
		}
Example #14
0
		/// <summary>
		/// 颜色饱和度是否太低
		/// </summary>
		/// <param name="hsvColor">颜色</param>
		/// <returns>Boolean值</returns>
		public static bool IsNotSaturateEnough(HSLColor color)
		{
			return color.Saturation < NotSaturateEnough;
		}
Example #15
0
		/// <summary>
		/// 计算两种颜色的差异。0为无差异,4.2为差异最大值
		/// </summary>
		/// <param name="c1">颜色1</param>
		/// <param name="c2">颜色2</param>
		/// <returns>差异值</returns>
		public static double Difference(HSLColor c1, HSLColor c2)
		{
			double AlphaDiff = Math.Abs(c1.Alpha - c2.Alpha);
			double HueDiff = Math.Min(Math.Abs(c1.Hue - c2.Hue), Math.Min(Math.Abs(c1.Hue + 360 - c2.Hue), Math.Abs(c1.Hue - c2.Hue - 360)));
			double SaturationDiff = Math.Abs(c1.Saturation - c2.Saturation);
			double LightnessDiff = Math.Abs(c1.Lightness - c2.Lightness);
			if (AlphaDiff + SaturationDiff + LightnessDiff > CoverColorDiff)
				return SaturationDiff + LightnessDiff;
			else
			{
				return HueDiff / 150 * Math.Min(c1.Saturation, c2.Saturation) * (0.5 - Math.Max(Math.Abs(c1.Lightness - 0.5), Math.Abs(c2.Lightness - 0.5))) * 2;
			}
			//return (Math.Abs(c1.Alpha - c2.Alpha) + HueDiff / 150 + Math.Abs(c1.Saturation - c2.Saturation) + Math.Abs(c1.Lightness - c2.Lightness));
		}
Example #16
0
		/// <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;
		}