途中まで書いたのですが、HTMLテーブルがうまくはたらかないので、詳細ははてなブログで。
[追記]書きました! こちらの記事です。→色温度からRGB(sRGB)に変換(完成版)
何をするの?
こういうの見たことありませんか? 色温度に対応するsRGB値を求めるコードを実装します。
処理の大筋
- 色温度の範囲チェック
- 色温度→xy色度座標
- xyz→線形sRGB
- 線形sRGBを規格化
- 線形sRGB→非線形sRGB
- 非線形sRGBを量子化(0〜255の整数)
- 量子化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;
}