色温度からRGB(sRGB)に変換

  • 2
    Like
  • 0
    Comment

 途中まで書いたのですが、HTMLテーブルがうまくはたらかないので、詳細ははてなブログで。
 [追記]書きました! こちらの記事です。→色温度からRGB(sRGB)に変換(完成版)

何をするの?

 こういうの見たことありませんか? 色温度に対応するsRGB値を求めるコードを実装します。

 daylight.png

処理の大筋

  1. 色温度の範囲チェック
  2. 色温度→xy色度座標
  3. xyz→線形sRGB
  4. 線形sRGBを規格化
  5. 線形sRGB→非線形sRGB
  6. 非線形sRGBを量子化(0〜255の整数)
  7. 量子化sRGB→0xAARRGGBB

コードはもちろんJava

 なぜなら、あなたもまた(以下略

    public static int daylight(double tcp) {
        double x, y, z, r, g, b;
        if (tcp < 4000.0) {
            throw new IllegalArgumentException();
        }
        else if (tcp <= 7000.0) {
            x = -4.6070E9 / (tcp * tcp * tcp) + 2.9678E6 / (tcp * tcp) + 0.09911E3 / tcp + 0.244063;
        }
        else if (tcp <= 25000.0) {
            x = -2.0064E9 / (tcp * tcp * tcp) + 1.9018E6 / (tcp * tcp) + 0.24748E3 / tcp + 0.237040;
        }
        else {
            throw new IllegalArgumentException();
        }
        y = -3.000 * (x * x) + 2.870 * x - 0.275;
        z = 1.0 - x - y;

        r = 3.2406 * x - 1.5372 * y - 0.4986 * z;
        g = -0.9689 * x + 1.8758 * y + 0.0415 * z;
        b = 0.0557 * x - 0.2040 * y + 1.0570 * z;

//      double maxRgb = Math.max(Math.max(r, g), b);
//      r /= maxRgb;
//      g /= maxRgb;
//      b /= maxRgb;
//      r = (r <= 0.0031308) ? 12.92 * r : 1.055 * Math.pow(r, 1.0 / 2.4) - 0.055;
//      g = (g <= 0.0031308) ? 12.92 * g : 1.055 * Math.pow(g, 1.0 / 2.4) - 0.055;
//      b = (b <= 0.0031308) ? 12.92 * b : 1.055 * Math.pow(b, 1.0 / 2.4) - 0.055;

//      上のコメントアウト部分は、今回のシチュエーションでは分岐を省略して
//      以下のようにできます

        double maxRgb = Math.max(Math.max(r, g), b);        
        r = 1.055 * Math.pow(r / maxRgb, 1.0 / 2.4) - 0.055;
        g = 1.055 * Math.pow(g / maxRgb, 1.0 / 2.4) - 0.055;
        b = 1.055 * Math.pow(b / maxRgb, 1.0 / 2.4) - 0.055;

        int rr = (int) (255.0 * r + 0.5);
        int gg = (int) (255.0 * g + 0.5);
        int bb = (int) (255.0 * b + 0.5);
        return 0xFF000000 | (rr << 16) | (gg << 8) | bb;
    }