예제 #1
0
 /// <summary>
 /// Linearly interpolates between two color values.
 /// </summary>
 /// <param name="from">The color value that represents 0 on the lerp number line.</param>
 /// <param name="to">The color value that represents 1 on the lerp number line.</param>
 /// <param name="frac">A value in the range [0, 1].</param>
 /// <remarks>
 /// This method does a simple lerp on each color value and on the alpha channel. It does
 /// not properly take into account the alpha channel's effect on color blending.
 /// </remarks>
 public static ColorBgra Lerp(ColorBgra from, ColorBgra to, double frac)
 {
     return FromBgraClamped(
         (((double)@from.B).Lerp(to.B, frac)),
         (((double)@from.G).Lerp(to.G, frac)),
         (((double)@from.R).Lerp(to.R, frac)),
         (((double)@from.A).Lerp(to.A, frac)));
 }
예제 #2
0
 private static SaveFormats.LinearColor BgraToLinearColor(ColorBgra bgra)
 {
     return new SaveFormats.LinearColor(
         (float)bgra.R / 255,
         (float)bgra.G / 255,
         (float)bgra.B / 255,
         (float)bgra.A / 255);
 }
예제 #3
0
        /// <summary>
        /// Blends the colors based on the given weight values.
        /// </summary>
        /// <param name="c">The array of color values.</param>
        /// <param name="w">The array of weight values.</param>
        /// <returns>
        /// Each color will be blended in proportionally to its weight value respective to 
        /// the total summation of the weight values.
        /// </returns>
        /// <remarks>
        /// "WAIP" stands for "weights, floating-point"</remarks>
        public static ColorBgra BlendColors(ColorBgra[] c, double[] w)
        {
            if (c.Length != w.Length)
            {
                throw new ArgumentException("c.Length != w.Length");
            }

            if (c.Length == 0)
            {
                return Transparent;
            }

            double wsum = 0;
            double asum = 0;

            for (int i = 0; i < w.Length; ++i)
            {
                wsum += w[i];
                asum += c[i].A * w[i];
            }

            double a = asum / wsum;
            double aMultWsum = a * wsum;

            double b;
            double g;
            double r;

            if (Equals(asum, 0.0) == true)
            {
                b = 0;
                g = 0;
                r = 0;
            }
            else
            {
                b = 0;
                g = 0;
                r = 0;

                for (int i = 0; i < c.Length; ++i)
                {
                    b += (double)c[i].A * c[i].B * w[i];
                    g += (double)c[i].A * c[i].G * w[i];
                    r += (double)c[i].A * c[i].R * w[i];
                }

                b /= aMultWsum;
                g /= aMultWsum;
                r /= aMultWsum;
            }

            return FromBgra((byte)b, (byte)g, (byte)r, (byte)a);
        }
예제 #4
0
        /// <summary>
        /// Blends the colors based on the given weight values.
        /// </summary>
        /// <param name="c">The array of color values.</param>
        /// <param name="w">The array of weight values.</param>
        /// <returns>
        /// The weights should be fixed point numbers. 
        /// The total summation of the weight values will be treated as "1.0".
        /// Each color will be blended in proportionally to its weight value respective to 
        /// the total summation of the weight values.
        /// </returns>
        /// <remarks>
        /// "WAIP" stands for "weights, arbitrary integer precision"</remarks>
        public static ColorBgra BlendColors(ColorBgra[] c, uint[] w)
        {
            if (c.Length != w.Length)
            {
                throw new ArgumentException("c.Length != w.Length");
            }

            if (c.Length == 0)
            {
                return FromUInt32(0);
            }

            long wsum = 0;
            long asum = 0;

            for (int i = 0; i < w.Length; ++i)
            {
                wsum += w[i];
                asum += c[i].A * w[i];
            }

            var a = (uint)((asum + (wsum >> 1)) / wsum);

            long b;
            long g;
            long r;

            if (a == 0)
            {
                b = 0;
                g = 0;
                r = 0;
            }
            else
            {
                b = 0;
                g = 0;
                r = 0;

                for (int i = 0; i < c.Length; ++i)
                {
                    b += (long)c[i].A * c[i].B * w[i];
                    g += (long)c[i].A * c[i].G * w[i];
                    r += (long)c[i].A * c[i].R * w[i];
                }

                b /= asum;
                g /= asum;
                r /= asum;
            }

            return FromUInt32((uint)b + ((uint)g << 8) + ((uint)r << 16) + (a << 24));
        }
예제 #5
0
        /// <summary>
        /// Blends four colors together based on the given weight values.
        /// </summary>
        /// <returns>The blended color.</returns>
        /// <remarks>
        /// The weights should be 16-bit fixed point numbers that add up to 65536 ("1.0").
        /// 4W16IP means "4 colors, weights, 16-bit integer precision"
        /// </remarks>
        public static ColorBgra BlendColors(ColorBgra c1,
            uint w1,
            ColorBgra c2,
            uint w2,
            ColorBgra c3,
            uint w3,
            ColorBgra c4,
            uint w4)
        {
            const uint ww = 32768;
            uint af = (c1.A * w1) + (c2.A * w2) + (c3.A * w3) + (c4.A * w4);
            uint a = (af + ww) >> 16;

            uint b;
            uint g;
            uint r;

            if (a == 0)
            {
                b = 0;
                g = 0;
                r = 0;
            }
            else
            {
                b =
                    (uint)
                    ((((long)c1.A * c1.B * w1) + ((long)c2.A * c2.B * w2) + ((long)c3.A * c3.B * w3) +
                      ((long)c4.A * c4.B * w4)) / af);
                g =
                    (uint)
                    ((((long)c1.A * c1.G * w1) + ((long)c2.A * c2.G * w2) + ((long)c3.A * c3.G * w3) +
                      ((long)c4.A * c4.G * w4)) / af);
                r =
                    (uint)
                    ((((long)c1.A * c1.R * w1) + ((long)c2.A * c2.R * w2) + ((long)c3.A * c3.R * w3) +
                      ((long)c4.A * c4.R * w4)) / af);
            }

            return FromBgra((byte)b, (byte)g, (byte)r, (byte)a);
        }
예제 #6
0
        /// <summary>
        /// Smoothly blends between two colors.
        /// </summary>
        public static ColorBgra Blend(ColorBgra ca, ColorBgra cb, byte cbAlpha)
        {
            uint caA = FastScaleByteByByte((byte)(255 - cbAlpha), ca.A);
            uint cbA = FastScaleByteByByte(cbAlpha, cb.A);
            uint cbAt = caA + cbA;

            uint r;
            uint g;
            uint b;

            if (cbAt == 0)
            {
                r = 0;
                g = 0;
                b = 0;
            }
            else
            {
                r = ((ca.R * caA) + (cb.R * cbA)) / cbAt;
                g = ((ca.G * caA) + (cb.G * cbA)) / cbAt;
                b = ((ca.B * caA) + (cb.B * cbA)) / cbAt;
            }

            return FromBgra((byte)b, (byte)g, (byte)r, (byte)cbAt);
        }
예제 #7
0
        private void SyncHsvFromRgb(ColorBgra bgra)
        {
            ColorHsv hsv = ColorHsv.FromColor(bgra.ToColor());

            this.SetColorGradientValuesHsv(hsv.Hue, hsv.Saturation, hsv.Value);
            this.SetColorGradientMinMaxColorsHsv(hsv.Hue, hsv.Saturation, hsv.Value);

            colorWheel1.Color = hsv;
        }