java 写 Lab转rgb、rgb转Lab

这段时间需要将Lab转成rgb,在网上找了好久,找到了好几个算法,结果一试,都不能如愿。

下面介绍一个 转化成中间量的方式来做:

一共4个方法:lab->xyz     xyz->lab    rgb->xyz     xyz->rgb

代码如下:


import java.lang.Math;

。。。。

public static double[] Lab2XYZ(double[] Lab) {
double[] XYZ = new double[3];
double L, a, b;
double fx, fy, fz;
double Xn, Yn, Zn;
Xn = 95.04;
Yn = 100;
Zn = 108.89;

L = Lab[0];
a = Lab[1];
b = Lab[2];

fy = (L + 16) / 116;
fx = a / 500 + fy;
fz = fy - b / 200;

if (fx > 0.2069) {
XYZ[0] = Xn * Math.pow(fx, 3);
} else {
XYZ[0] = Xn * (fx - 0.1379) * 0.1284;
}

if ((fy > 0.2069) || (L > 8)) {
XYZ[1] = Yn * Math.pow(fy, 3);
} else {
XYZ[1] = Yn * (fy - 0.1379) * 0.1284;
}

if (fz > 0.2069) {
XYZ[2] = Zn * Math.pow(fz, 3);
} else {
XYZ[2] = Zn * (fz - 0.1379) * 0.1284;
}

return XYZ;
}


public static double[] XYZ2Lab(double[] XYZ) {
double[] Lab = new double[3];
double X, Y, Z;
X = XYZ[0];
Y = XYZ[1];
Z = XYZ[2];
double Xn, Yn, Zn;
Xn = 95.04;
Yn = 100;
Zn = 108.89;
double XXn, YYn, ZZn;
XXn = X / Xn;
YYn = Y / Yn;
ZZn = Z / Zn;

double fx, fy, fz;

if (XXn > 0.008856) {
fx = Math.pow(XXn, 0.333333);
} else {
fx = 7.787 * XXn + 0.137931;
}

if (YYn > 0.008856) {
fy = Math.pow(YYn, 0.333333);
} else {
fy = 7.787 * YYn + 0.137931;
}

if (ZZn > 0.008856) {
fz = Math.pow(ZZn, 0.333333);
} else {
fz = 7.787 * ZZn + 0.137931;
}

Lab[0] = 116 * fy - 16;
Lab[1] = 500 * (fx - fy);
Lab[2] = 200 * (fy - fz);

return Lab;
}

测试结果:Lab(30,30,30)->lab2XYZ()得到

X: 9.0443297752659
Y: 6.235905531182091
Z: 1.6319698441408015

再将XYZ  -> XYZ2lab() 得到
L: 30.00004254766423   ==30
a: 29.999995585404005 == 30
b: 30.000004314463546 ==30

返回的结果基本上差不多


public static double[] sRGB2XYZ(double[] sRGB) {
double[] XYZ = new double[3];
double sR, sG, sB;
sR = sRGB[0];
sG = sRGB[1];
sB = sRGB[2];
sR /= 255;
sG /= 255;
sB /= 255;

if (sR <= 0.04045) {
sR = sR / 12.92;
} else {
sR = Math.pow(((sR + 0.055) / 1.055), 2.4);
}

if (sG <= 0.04045) {
sG = sG / 12.92;
} else {
sG = Math.pow(((sG + 0.055) / 1.055), 2.4);
}

if (sB <= 0.04045) {
sB = sB / 12.92;
} else {
sB = Math.pow(((sB + 0.055) / 1.055), 2.4);
}

XYZ[0] = 41.24 * sR + 35.76 * sG + 18.05 * sB;
XYZ[1] = 21.26 * sR + 71.52 * sG + 7.2 * sB;
XYZ[2] = 1.93 * sR + 11.92 * sG + 95.05 * sB;

return XYZ;
}


public static int[] XYZ2sRGB(double[] XYZ) {
int[] sRGB = new int[3];
double X, Y, Z;
double dr, dg, db;
X = XYZ[0];
Y = XYZ[1];
Z = XYZ[2];

dr = 0.032406 * X - 0.015371 * Y - 0.0049895 * Z;
dg = -0.0096891 * X + 0.018757 * Y + 0.00041914 * Z;
db = 0.00055708 * X - 0.0020401 * Y + 0.01057 * Z;

if (dr <= 0.00313) {
dr = dr * 12.92;
} else {
dr = Math.exp(Math.log(dr) / 2.4) * 1.055 - 0.055;
}

if (dg <= 0.00313) {
dg = dg * 12.92;
} else {
dg = Math.exp(Math.log(dg) / 2.4) * 1.055 - 0.055;
}

if (db <= 0.00313) {
db = db * 12.92;
} else {
db = Math.exp(Math.log(db) / 2.4) * 1.055 - 0.055;
}

dr = dr * 255;
dg = dg * 255;
db = db * 255;

dr = Math.min(255, dr);
dg = Math.min(255, dg);
db = Math.min(255, db);

sRGB[0] = (int) (dr + 0.5);
sRGB[1] = (int) (dg + 0.5);
sRGB[2] = (int) (db + 0.5);

return sRGB;
}


测试得到结果:

rgb(30,30,30) -> sRGB2XYZ() ,得到XYZ的值:

X :  1.2340372241235449
Y :  1.2980435735704576
Z :  1.413852222062641

再将XYZ -> XYZ2sRGB() ,得到rgb的值:
 r :  30
g :  30
b :  30

刚好得到原值







  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值