Пример #1
0
        /// <summary>
        /// transformatin CIE L*u*v* -> CIE XYZ
        /// </summary>
        /// <author>Birthe Anne Wiegand</author>
        /// <returns>XYZ value</returns>
        public XYZ asXYZ(XYZ WP)
        {
            XYZ temp = new XYZ();
            float temp_u = new float();
            float temp_v = new float();

            temp_u = this.U / (13f * this.L) + ColorHelper.function_XYZ_to_LUV(WP)[0];
            temp_v = this.V / (13f * this.L) + ColorHelper.function_XYZ_to_LUV(WP)[1];

            if (this.L <= 8)
            {
                temp.Y = WP.Y * this.L * 0.001107056f;
            }
            else
            {
                temp.Y = WP.Y * (float)Math.Pow(((this.L + 16f) / 116f), 3f);
            }
            temp.X = temp.Y * 9f * temp_u / (4f * temp_v);
            temp.Z = temp.Y * (12f - 3f * temp_u - 20f * temp_v) / (4f * temp_v);

            // to catch the otherwise occuring exception for L = 0 (black -> no color information)
            // X and Z are given the value 0 just for interface clarity as there is no information given about them.
            // (so 0 is as good as any other value, but does not imply anything wrong)
            if (float.IsNaN(temp.X)) temp.X = 0f;
            if (float.IsNaN(temp.Z)) temp.Z = 0f;

            return temp;
        }
Пример #2
0
        /// <summary>
        /// transformatin CIE L*a*b* -> CIE XYZ
        /// </summary>
        /// <author>Birthe Anne Wiegand</author>
        /// <returns>XYZ value</returns>
        public XYZ asXYZ(XYZ WP)
        {
            XYZ temp = new XYZ();

            temp.Y = WP.Y * function_LAB_to_XYZ((this.L + 16f) / 116f);
            temp.X = WP.X * function_LAB_to_XYZ((this.L + 16f) / 116f + this.A / 500);
            temp.Z = WP.Z * function_LAB_to_XYZ((this.L + 16f) / 116f - this.B / 200);

            return temp;
        }
Пример #3
0
        public XYZ asXYZ()
        {
            XYZ temp = new XYZ();

            // transformation Yxy -> CIE XYZ
            float normalizeFactor = this.Y / this.y;
            float Z = (1 - this.x - this.y) * normalizeFactor;

            temp.X = this.x * normalizeFactor;
            temp.Y = this.Y;
            temp.Z = Z;

            return temp;
        }
Пример #4
0
        public static float Chromatic_Difference(XYZ input1, XYZ input2)
        {
            // returns the chromatic difference of two colors given in the XYZ format
            // using the euclidean distance on the u' and v' values
            // (e.g. needed for the just noticeable difference (JND) calculation)
            // source: http://files.cie.co.at/738_CIE_TN_001-2014.pdf

            float temp = new float();
            Vector2 input1_vector = new Vector2();
            Vector2 input2_vector = new Vector2();

            input1_vector = function_XYZ_to_LUV(input1);
            input2_vector = function_XYZ_to_LUV(input2);

            temp = (float)Math.Sqrt((float)Math.Pow((input2_vector[0] - input1_vector[0]), 2f) + (float)Math.Pow((input2_vector[1] - input1_vector[1]), 2f));

            return temp;
        }
Пример #5
0
 /// <summary>
 /// this calclates the u' and v' values for a given XYZ value
 /// outsourced because it is used by more than one color class (mostly for L*u*v*, hence the name)
 /// source: http://en.wikipedia.org/wiki/CIELUV (checked with various google results, this was the most consistent one)
 /// </summary>
 /// <author>Birthe Anne Wiegand</author>
 /// <returns>a vector with u' in its first argument ([0]) and v' in the second ([1]), both floats</returns>
 public static Vector2 function_XYZ_to_LUV(XYZ input)
 {
     // calculates the u' and v' values for a given XYZ value
     // (needed for the transformation CIE XYZ -> CIE L*u*v* and back)
     // [0] gives the u' value and [1] the v' value
     Vector2 temp = new Vector2();
     temp[0] = (4f * input.X) / (input.X + 15f * input.Y + 3f * input.Z);
     temp[1] = (9f * input.Y) / (input.X + 15f * input.Y + 3f * input.Z);
     return temp;
 }
Пример #6
0
        /// <summary>
        /// (re-)sets (to) init values
        /// </summary>
        /// <author>Markus Strobel</author>
        private void setInitValues()
        {
            WP_default = WP_used = new XYZ(0.95045596f, 1f, 1.0890577f);
            RR_default = RR_used = new XYZ(0.64f, 0.33f, 0.03f);
            GG_default = GG_used = new XYZ(0.30f, 0.60f, 0.10f);
            BB_default = BB_used = new XYZ(0.15f, 0.06f, 0.79f);

            TranformationMatrices_Update();
        }
Пример #7
0
        /// <summary>
        /// </summary>
        /// <author> Birthe Anne Wiegand</author>
        private void ResetColorValues()
        {
            // set color values to 0
            RGBvalue = new RGB();
            customRGBvalue = new customRGB();
            sRGBvalue = new sRGB();
            HSLvalue = new HSL();
            HSVvalue = new HSV();
            XYZvalue = new XYZ();
            LUVvalue = new LUV();
            LABvalue = new LAB();

            UpdateBoxes();
        }
Пример #8
0
        /// <summary>
        /// this method performs all tasks done with a left mouse click in XYZ space
        /// </summary>
        /// <param name="x">the current x coordinate</param>
        /// <param name="y">the current y coordinate</param>
        /// <param name="showCircle">if true the selected Color circle will be shown</param>
        /// <author>Markus Strobel</author>
        private void LeftClickXYZSpace(float x, float y, bool showCircle)
        {
            // set trackbar values
            if (!(hoveredRGBColor.R < 0 || hoveredRGBColor.G < 0 || hoveredRGBColor.B < 0))
            {
                HSL hsl = hoveredRGBColor.asHSL();

                // normalize
                float maxV = Math.Max(hoveredRGBColor.R, Math.Max(hoveredRGBColor.G, hoveredRGBColor.B));
                hoveredRGBColor.R /= maxV;
                hoveredRGBColor.G /= maxV;
                hoveredRGBColor.B /= maxV;

                // set RGB tab values for trackbars
                labelTabRGB_R.Text = "R: " + hoveredRGBColor.R;
                labelTabRGB_G.Text = "G: " + hoveredRGBColor.G;
                labelTabRGB_B.Text = "B: " + hoveredRGBColor.B;
                trackBarR.Value = (int)(hoveredRGBColor.R * 255);
                trackBarG.Value = (int)(hoveredRGBColor.G * 255);
                trackBarB.Value = (int)(hoveredRGBColor.B * 255);

                //set HSL values for trackbars
                labelTabHSL_H.Text = "H: " + (hsl.H) + "°";
                labelTabHSL_S.Text = "S: " + (hsl.S * 100) + "%";
                labelTabHSL_L.Text = "L: " + (hsl.L * 100) + "%";
                trackBarH.Value = (int)hsl.H;
                trackBarS.Value = (int)(hsl.S * 100);
                trackBarL.Value = (int)(hsl.L * 100);

                selectedRGBColor = hoveredRGBColor;
                selectedXYZColor = hoveredXYZColor;
                selectedYxyColor = new Yxy(x, y);

                if (checkBoxRGB.Checked)
                {
                    showColorCircle = false;
                    createRGBPreviewLines(selectedRGBColor);
                }
                else if (checkBoxHSL.Checked)
                {
                    showColorCircle = false;
                    createHSLPreviewLines(selectedRGBColor.asHSL());
                    createHSLPreviewCircle(selectedRGBColor.asHSL());
                }
                else
                {
                    showColorCircle = showCircle;
                    createSelectedColorCircleVBO(x, y, 0.01f, 36); // computes color circle position
                }
            }
            else // (!(hoveredRGBColor.R < 0 || hoveredRGBColor.G < 0 || hoveredRGBColor.B < 0))
            {
                trackBarR.Value = 0;
                trackBarG.Value = 0;
                trackBarB.Value = 0;
                labelTabRGB_R.Text = "R: 0";
                labelTabRGB_G.Text = "G: 0";
                labelTabRGB_B.Text = "B: 0";
                trackBarH.Value = 1;
                trackBarS.Value = 100;
                trackBarL.Value = 50;
                labelTabHSL_H.Text = "H: 1°";
                labelTabHSL_S.Text = "S: 100%";
                labelTabHSL_L.Text = "L: 50%";

                selectedRGBColor = null;
                selectedXYZColor = null;
                showColorCircle = false;
            }

            // take current preview Color as selected Color
            // we dont need to compute it twice
            // set selectedColor Panel, label
            panelColorSelected.BackColor = panelColorPreview.BackColor;
            labelColorSelectedHex.Text = labelColorPreviewHex.Text;
            labelColSelectedXH.Text = labelColPreviewXH.Text;
            labelColSelectedYS.Text = labelColPreviewYS.Text;
        }
Пример #9
0
        /// <summary>
        /// </summary>
        /// <author> Birthe Anne Wiegand</author>
        private void KonvertierenButton_Click(object sender, EventArgs e)
        {
            RadioButton checkedButton = this.tabFarbRechner.Controls.OfType<RadioButton>().FirstOrDefault(radioButton => radioButton.Checked);

            switch (checkedButton.Name)
            {
                case "customRGB":
                    // parse input to internal customRGBvalue
                    customRGBvalue.R = float.Parse(customRGB_R.Text, CultureInfo.InvariantCulture);
                    customRGBvalue.G = float.Parse(customRGB_G.Text, CultureInfo.InvariantCulture);
                    customRGBvalue.B = float.Parse(customRGB_B.Text, CultureInfo.InvariantCulture);

                    // update other internal values
                    XYZvalue = customRGBvalue.asXYZ();
                    RGBvalue = XYZvalue.asRGB();
                    sRGBvalue = RGBvalue.as_sRGB();
                    HSLvalue = RGBvalue.asHSL();
                    HSVvalue = RGBvalue.asHSV();
                    LUVvalue = XYZvalue.asLUV();
                    LABvalue = XYZvalue.asLAB();
                    break;
                case "sRGB":
                    // parse input to internal customRGBvalue
                    sRGBvalue.R = float.Parse(sRGB_R.Text, CultureInfo.InvariantCulture);
                    sRGBvalue.G = float.Parse(sRGB_G.Text, CultureInfo.InvariantCulture);
                    sRGBvalue.B = float.Parse(sRGB_B.Text, CultureInfo.InvariantCulture);

                    // update other internal values
                    RGBvalue = sRGBvalue.asRGB();
                    XYZvalue = RGBvalue.asXYZ();
                    customRGBvalue = XYZvalue.as_customRGB();
                    HSLvalue = RGBvalue.asHSL();
                    HSVvalue = RGBvalue.asHSV();
                    LUVvalue = XYZvalue.asLUV();
                    LABvalue = XYZvalue.asLAB();
                    break;
                case "HSL":
                    // parse input to internal HSLvalue
                    HSLvalue.H = float.Parse(HSL_H.Text, CultureInfo.InvariantCulture);
                    HSLvalue.S = float.Parse(HSL_S.Text, CultureInfo.InvariantCulture);
                    HSLvalue.L = float.Parse(HSL_L.Text, CultureInfo.InvariantCulture);

                    // update other internal values
                    RGBvalue = HSLvalue.asRGB();
                    XYZvalue = RGBvalue.asXYZ();
                    customRGBvalue = XYZvalue.as_customRGB();
                    sRGBvalue = RGBvalue.as_sRGB();
                    HSVvalue = RGBvalue.asHSV();
                    LUVvalue = XYZvalue.asLUV();
                    LABvalue = XYZvalue.asLAB();
                    break;
                case "HSV":
                    // parse input to internal HSVvalue
                    HSVvalue.H = float.Parse(HSV_H.Text, CultureInfo.InvariantCulture);
                    HSVvalue.S = float.Parse(HSV_S.Text, CultureInfo.InvariantCulture);
                    HSVvalue.V = float.Parse(HSV_V.Text, CultureInfo.InvariantCulture);

                    // update other internal values
                    RGBvalue = HSVvalue.asRGB();
                    XYZvalue = RGBvalue.asXYZ();
                    customRGBvalue = XYZvalue.as_customRGB();
                    sRGBvalue = RGBvalue.as_sRGB();
                    HSLvalue = RGBvalue.asHSL();
                    LUVvalue = XYZvalue.asLUV();
                    LABvalue = XYZvalue.asLAB();
                    break;
                case "XYZ":
                    // parse input to internal HSVvalue
                    XYZvalue.X = float.Parse(XYZ_X.Text, CultureInfo.InvariantCulture);
                    XYZvalue.Y = float.Parse(XYZ_Y.Text, CultureInfo.InvariantCulture);
                    XYZvalue.Z = float.Parse(XYZ_Z.Text, CultureInfo.InvariantCulture);

                    // update other internal values
                    RGBvalue = XYZvalue.asRGB();
                    customRGBvalue = XYZvalue.as_customRGB();
                    sRGBvalue = RGBvalue.as_sRGB();
                    HSLvalue = RGBvalue.asHSL();
                    HSVvalue = RGBvalue.asHSV();
                    LUVvalue = XYZvalue.asLUV(ColorHelper.WP_used);
                    LABvalue = XYZvalue.asLAB(ColorHelper.WP_used);
                    break;
                case "LUV":
                    // parse input to internal LUVvalue
                    LUVvalue.L = float.Parse(LUV_L.Text, CultureInfo.InvariantCulture);
                    LUVvalue.U = float.Parse(LUV_U.Text, CultureInfo.InvariantCulture);
                    LUVvalue.V = float.Parse(LUV_V.Text, CultureInfo.InvariantCulture);

                    // update other internal values
                    XYZvalue = LUVvalue.asXYZ(ColorHelper.WP_used);
                    RGBvalue = XYZvalue.asRGB();
                    customRGBvalue = XYZvalue.as_customRGB();
                    sRGBvalue = RGBvalue.as_sRGB();
                    HSLvalue = RGBvalue.asHSL();
                    HSVvalue = RGBvalue.asHSV();
                    LABvalue = XYZvalue.asLAB(ColorHelper.WP_used);
                    break;
                case "LAB":
                    // parse input to internal LABvalue
                    LABvalue.L = float.Parse(LAB_L.Text, CultureInfo.InvariantCulture);
                    LABvalue.A = float.Parse(LAB_A.Text, CultureInfo.InvariantCulture);
                    LABvalue.B = float.Parse(LAB_B.Text, CultureInfo.InvariantCulture);

                    // update other internal values
                    XYZvalue = LABvalue.asXYZ(ColorHelper.WP_used);
                    RGBvalue = XYZvalue.asRGB();
                    customRGBvalue = XYZvalue.as_customRGB();
                    sRGBvalue = RGBvalue.as_sRGB();
                    HSLvalue = RGBvalue.asHSL();
                    HSVvalue = RGBvalue.asHSV();
                    LUVvalue = XYZvalue.asLUV(ColorHelper.WP_used);
                    break;
            }

            UpdateBoxes();
        }
Пример #10
0
        /// <summary>
        /// mouse hover ofer the OpenGL Window will be handled here
        /// </summary>
        /// <author>Markus Strobel</author>
        private void glControl_MouseHover(object sender, System.EventArgs e)
        {
            // Get current mouse position within the glControl
            Point mousePos = glControl1.PointToClient(Cursor.Position);
            // get x,y relative to an origin in the bottom left
            float x = mousePos.X;
            float y = glControl1.Height - mousePos.Y;

            // normalize to 0..1
            x /= glControl1.Width;
            y /= glControl1.Height;

            if (radioButtonXYZView.Checked)
            {
                Yxy Yxy = new Yxy(x, y);
                hoveredXYZColor = Yxy.asXYZ();
                hoveredRGBColor = hoveredXYZColor.asRGB(); //FarbRechner.CIEXYZ_to_RGB(FarbRechner.CIEYxy_to_CIEXYZ(Yxy));

                x = (float)Math.Round((double)x, 2);
                y = (float)Math.Round((double)y, 2);

                // filter negative rgb values
                if (!(hoveredRGBColor.R < 0 || hoveredRGBColor.G < 0 || hoveredRGBColor.B < 0))
                {
                    try
                    {
                        // normalize
                        float maxV = Math.Max(hoveredRGBColor.R, Math.Max(hoveredRGBColor.G, hoveredRGBColor.B));
                        hoveredRGBColor.R /= maxV;
                        hoveredRGBColor.G /= maxV;
                        hoveredRGBColor.B /= maxV;

                        // gamma correction
                        hoveredRGBColor.R = ColorHelper.Reverse_Gamma_Correction(hoveredRGBColor.R);
                        hoveredRGBColor.G = ColorHelper.Reverse_Gamma_Correction(hoveredRGBColor.G);
                        hoveredRGBColor.B = ColorHelper.Reverse_Gamma_Correction(hoveredRGBColor.B);

                        panelColorPreview.BackColor = Color.FromArgb((int)(hoveredRGBColor.R * 255), (int)(hoveredRGBColor.G * 255), (int)(hoveredRGBColor.B * 255));
                        labelColorPreviewHex.Text = "#" + ((int)(hoveredRGBColor.R * 255)).ToString("X") + ((int)(hoveredRGBColor.G * 255)).ToString("X") + ((int)(hoveredRGBColor.B * 255)).ToString("X");
                    }
                    catch
                    {
                        labelColorPreviewHex.Text = "#000";
                        panelColorPreview.BackColor = Color.Black;
                    }
                }
                else
                {
                    labelColorPreviewHex.Text = "#000";
                    panelColorPreview.BackColor = Color.Black;
                }
                labelColPreviewXH.Text = "x: " + x.ToString();
                labelColPreviewYS.Text = "y: " + y.ToString();
            }
        }
Пример #11
0
        /// <summary>
        /// transformatin CIE XYZ -> CIE L*a*b*
        /// source: http://en.wikipedia.org/wiki/CIELUV
        /// </summary>
        /// <author>Birthe Anne Wiegand</author>
        /// <returns>L*u*v* value</returns>
        public LUV asLUV(XYZ WP)
        {
            LUV temp = new LUV();

            float XXn = this.X / WP.X; // X / Xn
            float YYn = this.Y / WP.Y; // Y / Yn
            float ZZn = this.Z / WP.Z; // Z / Zn

            if (YYn <= 0.008856452)
            {
                temp.L = 903.2962963f * YYn;
            }
            else
            {
                temp.L = 116f * (float)Math.Pow(YYn, (1f / 3f)) - 16;
            }
            temp.U = 13f * temp.L * (ColorHelper.function_XYZ_to_LUV(this)[0] - ColorHelper.function_XYZ_to_LUV(WP)[0]);
            temp.V = 13f * temp.L * (ColorHelper.function_XYZ_to_LUV(this)[1] - ColorHelper.function_XYZ_to_LUV(WP)[1]);

            // to catch the otherwise occuring exception for (input.X + 15f * input.Y + 3f * input.Z) = 0
            // (ColorHelper.function_XYZ_to_LUV divides by zero if (input.X + 15f * input.Y + 3f * input.Z) = 0)
            // u* and v* are given the value 0 just for interface clarity as there is no information given about them.
            // (so 0 is as good as any other value, but does not imply anything wrong)
            if (float.IsNaN(temp.U)) temp.U = 0f;
            if (float.IsNaN(temp.V)) temp.V = 0f;

            return temp;
        }
Пример #12
0
        /// <summary>
        /// transformatin CIE XYZ -> CIE L*u*v*
        /// source: http://www.farbmetrik-gall.de/cielab/index.html, http://en.wikipedia.org/wiki/Lab_color_space
        /// </summary>
        /// <author>Birthe Anne Wiegand</author>
        /// <returns>L*a*b* value</returns>
        public LAB asLAB(XYZ WP)
        {
            LAB temp = new LAB();

            float XXn = this.X / WP.X; // X / Xn
            float YYn = this.Y / WP.Y; // Y / Yn
            float ZZn = this.Z / WP.Z; // Z / Zn

            temp.L = 116f * function_XYZ_to_LAB(YYn) - 16f;
            temp.A = 500f * (function_XYZ_to_LAB(XXn) - function_XYZ_to_LAB(YYn));
            temp.B = 200f * (function_XYZ_to_LAB(YYn) - function_XYZ_to_LAB(ZZn));

            return temp;
        }