예제 #1
0
        /// <summary>
        /// Transform linear RGB values to nonlinear RGB values. Rec.
        /// 709 is ITU-R Recommendation BT. 709 (1990) ``Basic
        /// Parameter Values for the HDTV Standard for the Studio and
        /// for International Programme Exchange'', formerly CCIR Rec.
        /// 709. For details see
        ///
        ///     http://www.poynton.com/ColorFAQ.html
        ///     http://www.poynton.com/GammaFAQ.html
        ///
        /// </summary>
        /// <param name="cs"></param>
        /// <param name="c"></param>
        static void gamma_correct(ColourSystem cs, ref double c)
        {
            double gamma;

            gamma = cs.Gamma;

            if (gamma == ColourSystems.GAMMA_REC709)
            {
                // Rec. 709 gamma correction.
                double cc = 0.018;

                if (c < cc)
                {
                    c *= ((1.099 * Math.Pow(cc, 0.45)) - 0.099) / cc;
                }
                else
                {
                    c = (1.099 * Math.Pow(c, 0.45)) - 0.099;
                }
            }
            else
            {
                // Nonlinear colour = (Linear colour)^(1/gamma)
                c = Math.Pow(c, 1.0 / gamma);
            }
        }
예제 #2
0
        public static Color FromTemp(this Color col, double temp, ColourSystem cs)
        {
            double r, g, b;

            RgbFromTemp(temp, out r, out g, out b, cs);
            return(Color.FromArgb(255, (int)r * 255, (int)r * 255, (int)r * 255));
        }
예제 #3
0
 static void gamma_correct_rgb(ColourSystem cs, ref double r, ref double g, ref double b)
 {
     gamma_correct(cs, ref r);
     gamma_correct(cs, ref g);
     gamma_correct(cs, ref b);
 }
예제 #4
0
        /// <summary>
        ///    Given an additive tricolour system CS, defined by the CIE x
        ///    and y chromaticities of its three primaries (z is derived
        ///    trivially as 1-(x+y)), and a desired chromaticity (XC, YC,
        ///    ZC) in CIE space, determine the contribution of each
        ///    primary in a linear combination which sums to the desired
        ///    chromaticity.  If the  requested chromaticity falls outside
        ///    the Maxwell  triangle (colour gamut) formed by the three
        ///    primaries, one of the r, g, or b weights will be negative.
        ///
        ///    Caller can use constrain_rgb() to desaturate an
        ///    outside-gamut colour to the closest representation within
        ///    the available gamut and/or norm_rgb to normalise the RGB
        ///    components so the largest nonzero component has value 1.
        /// </summary>
        /// <param name="cs"></param>
        /// <param name="xc"></param>
        /// <param name="yc"></param>
        /// <param name="zc"></param>
        /// <param name="r"></param>
        /// <param name="g"></param>
        /// <param name="b"></param>
        public static void XyzToRgb(ColourSystem cs,
                                    double xc, double yc, double zc,
                                    out double r, out double g, out double b)
        {
            double xr, yr, zr, xg, yg, zg, xb, yb, zb;
            double xw, yw, zw;
            double rx, ry, rz, gx, gy, gz, bx, by, bz;
            double rw, gw, bw;

            xr = cs.Red.X;
            yr = cs.Red.Y;
            zr = 1 - (xr + yr);

            xg = cs.Green.X;
            yg = cs.Green.Y;
            zg = 1 - (xg + yg);

            xb = cs.Blue.X;
            yb = cs.Blue.Y;
            zb = 1 - (xb + yb);

            xw = cs.White.X;
            yw = cs.White.Y;
            zw = 1 - (xw + yw);

            // xyz -> rgb matrix, before scaling to white.
            rx = (yg * zb) - (yb * zg);
            ry = (xb * zg) - (xg * zb);
            rz = (xg * yb) - (xb * yg);

            gx = (yb * zr) - (yr * zb);
            gy = (xr * zb) - (xb * zr);
            gz = (xb * yr) - (xr * yb);

            bx = (yr * zg) - (yg * zr);
            by = (xg * zr) - (xr * zg);
            bz = (xr * yg) - (xg * yr);

            // White scaling factors.
            // Dividing by yw scales the white luminance to unity, as conventional.
            rw = ((rx * xw) + (ry * yw) + (rz * zw)) / yw;
            gw = ((gx * xw) + (gy * yw) + (gz * zw)) / yw;
            bw = ((bx * xw) + (by * yw) + (bz * zw)) / yw;

            // xyz -> rgb matrix, correctly scaled to white.
            rx = rx / rw;
            ry = ry / rw;
            rz = rz / rw;

            gx = gx / gw;
            gy = gy / gw;
            gz = gz / gw;

            bx = bx / bw;
            by = by / bw;
            bz = bz / bw;

            // rgb of the desired point
            r = (rx * xc) + (ry * yc) + (rz * zc);
            g = (gx * xc) + (gy * yc) + (gz * zc);
            b = (bx * xc) + (by * yc) + (bz * zc);
        }
예제 #5
0
        private static void RgbFromTemp(double temp, out double r, out double g, out double b, ColourSystem cs)
        {
            double x, y, z;

            Kernel.SpectrumToXyz((double waveLength) => { return(Kernel.BlackBodySpectrum(waveLength, temp)); }, out x, out y, out z);
            Kernel.XyzToRgb(cs, x, y, z, out r, out g, out b);

            if (Kernel.ConstrainRgb(ref r, ref g, ref b))
            {
                Kernel.NormRgb(ref r, ref g, ref b);
            }
            else
            {
                Kernel.NormRgb(ref r, ref g, ref b);
            }
        }