Converts color components from the CIE L*u*v* to the sRGB color space. - Java Swing

Java examples for Swing:JComponent

Description

Converts color components from the CIE L*u*v* to the sRGB color space.

Demo Code


import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics2D;
import java.awt.Paint;
import java.awt.Shape;
import java.awt.Stroke;
import java.awt.font.FontRenderContext;
import java.awt.font.LineBreakMeasurer;
import java.awt.font.TextAttribute;
import java.awt.font.TextLayout;
import java.awt.geom.AffineTransform;
import java.awt.geom.Area;
import java.awt.geom.Rectangle2D;
import java.text.AttributedCharacterIterator;
import java.text.AttributedString;
import java.util.LinkedList;
import java.util.List;

public class Main{
    /**/*w  w  w.j a  va 2s  . c  om*/
     * Constant for the CIE XYZ and CIE L*u*v* color spaces: (6/29)^3 *
     */
    private static final double CIE_EPSILON = 216.0 / 24389.0;
    /**
     * Constant for the CIE XYZ and CIE L*u*v* color spaces: (29/3)^3 *
     */
    private static final double CIE_KAPPA = 24389.0 / 27.0;
    /**
     * Precalculated u0 constant for CIE L*u*v* to CIE XYZ conversion. *
     */
    private static final double XYZ_R_D50_U0 = 4.0 * XYZ_R_D50[0]
            / (XYZ_R_D50[0] + 15.0 * XYZ_R_D50[1] + 3.0 * XYZ_R_D50[2]);
    /**
     * Precalculated v0 constant for CIE L*u*v* to CIE XYZ conversion. *
     */
    private static final double XYZ_R_D50_V0 = 9.0 * XYZ_R_D50[1]
            / (XYZ_R_D50[0] + 15.0 * XYZ_R_D50[1] + 3.0 * XYZ_R_D50[2]);
    /**
     * CIE XYZ to sRGB conversion matrix. See
     * http://www.brucelindbloom.com/index.html?WorkingSpaceInfo.html#Specifications *
     */
    private static final double[] MATRIX_XYZ2SRGB_D50 = { 3.1338561,
            -1.6168667, -0.4906146, -0.9787684, 1.9161415, 0.0334540,
            0.0719453, -0.2289914, 1.4052427 };
    /**
     * Converts color components from the CIE L*u*v* to the sRGB color space.
     * A D50 white point is assumed for the sRGB conversion. If the <i>rgb</i>
     * array is {@code null}, a new one will be created with the same size
     * as the <i>luv</i> array.
     *
     * @param luv Color components in the CIE L*u*v* color space.
     * @param rgb Optional array for storing color components in the sRGB color
     *            space.
     * @return Color components in sRGB color space.
     */
    public static double[] luv2rgb(double[] luv, double[] rgb) {
        double[] xyz = luv2xyz(luv, null);
        return xyz2rgb(xyz, rgb);
    }
    /**
     * Convert color components from the CIE L*u*v* to the CIE XYZ color space.
     * If the <i>xyz</i> array is {@code null}, a new one will be created
     * with the same size as the <i>luv</i> array.
     *
     * See http://www.brucelindbloom.com/index.html?Eqn_Luv_to_XYZ.html
     *
     * @param luv Color components in the CIE L*u*v* color space
     * @param xyz Optional array to store color components in the CIE XYZ color
     *            space.
     * @return Color components in the CIE XYZ color space.
     */
    public static double[] luv2xyz(double[] luv, double[] xyz) {
        if (xyz == null) {
            xyz = new double[luv.length];
        }

        if (luv[0] > CIE_KAPPA * CIE_EPSILON) {
            xyz[1] = (luv[0] + 16.0) / 116.0;
            xyz[1] = xyz[1] * xyz[1] * xyz[1];
        } else {
            xyz[1] = luv[0] / CIE_KAPPA;
        }

        double a = (luv[0] != 0.0 || luv[1] != 0.0) ? ((52.0 * luv[0])
                / (luv[1] + 13.0 * luv[0] * XYZ_R_D50_U0) - 1.0) / 3.0
                : 0.0;
        double b = -5 * xyz[1];
        double c = -1.0 / 3.0;
        double d = (luv[0] != 0.0 || luv[2] != 0.0) ? xyz[1]
                * ((39.0 * luv[0])
                        / (luv[2] + 13.0 * luv[0] * XYZ_R_D50_V0) - 5.0)
                : 0.0;

        xyz[0] = !MathUtils.almostEqual(a, c, 1e-15) ? (d - b) / (a - c)
                : 0.0;
        xyz[2] = xyz[0] * a + b;

        return xyz;
    }
    /**
     * Converts color components from the sRGB to the CIE XYZ color space.
     * A D50 white point is assumed for the sRGB conversion. If the <i>rgb</i>
     * array is {@code null}, a new one will be created with the same
     * size as the <i>xyz</i> array.
     *
     * See http://www.brucelindbloom.com/index.html?Eqn_XYZ_to_RGB.html
     *
     * @param xyz Color components in the CIE XYZ color space.
     * @param rgb Optional array for storing color components in the sRGB color
     *            space.
     * @return Color components in the sRGB color space.
     */
    public static double[] xyz2rgb(double[] xyz, double[] rgb) {
        if (rgb == null) {
            rgb = new double[xyz.length];
        }

        // XYZ to linear sRGB with D50 white point
        for (int i = 0; i < xyz.length; i++) {
            rgb[i] = MATRIX_XYZ2SRGB_D50[i * 3 + 0] * xyz[0]
                    + MATRIX_XYZ2SRGB_D50[i * 3 + 1] * xyz[1]
                    + MATRIX_XYZ2SRGB_D50[i * 3 + 2] * xyz[2];
        }

        // Apply sRGB companding
        for (int i = 0; i < rgb.length; i++) {
            if (rgb[i] <= 0.0031308) {
                rgb[i] = 12.92 * rgb[i];
            } else {
                rgb[i] = 1.055 * Math.pow(rgb[i], 1.0 / 2.4) - 0.055;
            }
        }

        return rgb;
    }
}

Related Tutorials