예제 #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());
            }));
        }
예제 #2
0
 /// <summary>
 /// 将颜色调暗一些
 /// </summary>
 /// <param name="hsvColor">待修正色</param>
 /// <returns>修正色</returns>
 public static HSLColor ReviseDarker(HSLColor color)
 {
     return ReviseDarker(color, ReviseParameter);
 }
예제 #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);
 }
예제 #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));
 }
예제 #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);
 }
예제 #6
0
 /// <summary>
 /// 将颜色调整到能够接受的最高亮度
 /// </summary>
 /// <param name="hsvColor">待修正色</param>
 /// <returns>修正色</returns>
 public static HSLColor ReviseVeryBright(HSLColor color)
 {
     return ReviseBrighter(color, TooBright - color.Lightness);
 }
예제 #7
0
 /// <summary>
 /// 将颜色调整到能够接受的最低亮度
 /// </summary>
 /// <param name="hsvColor">待修正色</param>
 /// <returns>修正色</returns>
 public static HSLColor ReviseVeryDark(HSLColor color)
 {
     return ReviseDarker(color, color.Lightness - TooDark);
 }
예제 #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;

        }
예제 #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;
     }
 }
예제 #10
0
 /// <summary>
 /// 颜色是否太亮
 /// </summary>
 /// <param name="hsvColor">颜色</param>
 /// <returns>Boolean值</returns>
 public static bool IsTooBright(HSLColor color)
 {
     return color.Lightness > TooBright;
 }
예제 #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);
 }
예제 #12
0
 /// <summary>
 /// 颜色是否太暗
 /// </summary>
 /// <param name="hsvColor">颜色</param>
 /// <returns>Boolean值</returns>
 public static bool IsTooDark(HSLColor color)
 {
     return color.Lightness < TooDark;
 }
예제 #13
0
 /// <summary>
 /// 颜色饱和度是否接近0
 /// </summary>
 /// <param name="hsvColor">颜色</param>
 /// <returns>Boolean值</returns>
 public static bool IsAlmostZeroSaturation(HSLColor color)
 {
     return color.Saturation < AlmostZeroSaturation;
 }
예제 #14
0
 /// <summary>
 /// 颜色饱和度是否太低
 /// </summary>
 /// <param name="hsvColor">颜色</param>
 /// <returns>Boolean值</returns>
 public static bool IsNotSaturateEnough(HSLColor color)
 {
     return color.Saturation < NotSaturateEnough;
 }
예제 #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));
 }
예제 #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;
 }