/// <summary> /// 异步从图片中获取背景颜色 /// </summary> /// <param name="image">图片</param> /// <param name="callback">计算完成后调用的委托</param> public static void GetImageColorForBackgroundAsync(BitmapSource image, ComputeCompleteCallback callback) { FormatConvertedBitmap bitmap = null; bool isFrozen = image.IsFrozen; if (!isFrozen) { //由于image没有冻结,所以image不能跨线程使用,这时要在当前线程中将image转换为另一个位图 bitmap = new FormatConvertedBitmap(image, PixelFormats.Rgb24, BitmapPalettes.WebPalette, 0); } ThreadPool.QueueUserWorkItem(state => { if (isFrozen) { //由于image已经冻结,所以image可以跨线程使用,这时在新线程中将image转换为另一个位图 bitmap = new FormatConvertedBitmap(image, PixelFormats.Rgb24, BitmapPalettes.WebPalette, 0); } callback(GetImageColorForBackground(bitmap)); }); }
/// <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()); })); }