RGB转LAB

RGB不能直接转成LAB,需要先转成XYZ,然后在从XYZ转成LAB。

RGB和XYZ和LAB可以理解为同一类颜色空间。

/**
     * Convert RGB components to its CIE Lab representative components.
     *
     * 
    *
  • outLab[0] is L [0 ...1)
  • *
  • outLab[1] is a [-128...127)
  • *
  • outLab[2] is b [-128...127)
  • *
* * @param r red component value [0..255] * @param g green component value [0..255] * @param b blue component value [0..255] * @param outLab 3-element array which holds the resulting LAB components */ public static void RGBToLAB(@IntRange(from = 0x0, to = 0xFF) int r, @IntRange(from = 0x0, to = 0xFF) int g, @IntRange(from = 0x0, to = 0xFF) int b, @NonNull double[] outLab) { //outLab就是要输出的内存地址 RGBToXYZ(r, g, b, outLab); // outLab now contains XYZ XYZToLAB(outLab[0], outLab[1], outLab[2], outLab); // outLab now contains LAB representation }

RGB的数值范围都是0~255

这一步就是将RGB归一化为XYZ:
0 ~ 255归一化为0 ~ 1
就是i/255(i= [0,255])

   /**
     * Convert RGB components to it's CIE XYZ representative components.
     *
     * 
     * 

The resulting XYZ representation will use the D65 illuminant and the CIE * 2° Standard Observer (1931).

* *
    *
  • outXyz[0] is X [0 ...95.047)
  • *
  • outXyz[1] is Y [0...100)
  • *
  • outXyz[2] is Z [0...108.883)
  • *
* * @param r red component value [0..255] * @param g green component value [0..255] * @param b blue component value [0..255] * @param outXyz 3-element array which holds the resulting XYZ components */ public static void RGBToXYZ(@IntRange(from = 0x0, to = 0xFF) int r, @IntRange(from = 0x0, to = 0xFF) int g, @IntRange(from = 0x0, to = 0xFF) int b, @NonNull double[] outXyz) { // 要保证RGB三通道不为空 if (outXyz.length != 3) { throw new IllegalArgumentException("outXyz must have a length of 3."); } //下面的可以理解为固定值,有固有算法 double sr = r / 255.0; sr = sr < 0.04045 ? sr / 12.92 : Math.pow((sr + 0.055) / 1.055, 2.4); double sg = g / 255.0; sg = sg < 0.04045 ? sg / 12.92 : Math.pow((sg + 0.055) / 1.055, 2.4); double sb = b / 255.0; sb = sb < 0.04045 ? sb / 12.92 : Math.pow((sb + 0.055) / 1.055, 2.4); //分别写入RGB三通道内存地址 outXyz[0] = 100 * (sr * 0.4124 + sg * 0.3576 + sb * 0.1805); outXyz[1] = 100 * (sr * 0.2126 + sg * 0.7152 + sb * 0.0722); outXyz[2] = 100 * (sr * 0.0193 + sg * 0.1192 + sb * 0.9505); }

然后再从XYZ转成LAB,因为是直接写进内存的,所以不需要通过返回值传递,而是直接通过内存地址拿值

    private static final double XYZ_WHITE_REFERENCE_X = 95.047;
    private static final double XYZ_WHITE_REFERENCE_Y = 100;
    private static final double XYZ_WHITE_REFERENCE_Z = 108.883;
    /**
     * Converts a color from CIE XYZ to CIE Lab representation.
     *
     * 

This method expects the XYZ representation to use the D65 illuminant and the CIE * 2° Standard Observer (1931).

* *
    *
  • outLab[0] is L [0 ...1)
  • *
  • outLab[1] is a [-128...127)
  • *
  • outLab[2] is b [-128...127)
  • *
* * @param x X component value [0...95.047) * @param y Y component value [0...100) * @param z Z component value [0...108.883) * @param outLab 3-element array which holds the resulting Lab components */ public static void XYZToLAB(@FloatRange(from = 0f, to = XYZ_WHITE_REFERENCE_X) double x, @FloatRange(from = 0f, to = XYZ_WHITE_REFERENCE_Y) double y, @FloatRange(from = 0f, to = XYZ_WHITE_REFERENCE_Z) double z, @NonNull double[] outLab) { if (outLab.length != 3) { throw new IllegalArgumentException("outLab must have a length of 3."); } //归一化组件 x = pivotXyzComponent(x / XYZ_WHITE_REFERENCE_X); y = pivotXyzComponent(y / XYZ_WHITE_REFERENCE_Y); z = pivotXyzComponent(z / XYZ_WHITE_REFERENCE_Z); //写RGB到内存地址 outLab[0] = Math.max(0, 116 * y - 16); outLab[1] = 500 * (x - y); outLab[2] = 200 * (y - z); }

csdn上这篇也不错
http://blog.csdn.net/scarecrow_wiscom/article/details/9795715

你可能感兴趣的:(RGB转LAB)