-
// RGBYUV -
// RGBXYZ -
// RGBLAB -
// RGBHSV -
// RGBCMY -
// XYZLAB -
// YUV ->XYZ -
// LAB ->HSV -
// XYZ ->HSV -
// RGB ->CMYK -
// CMYK->CMY -
// http://www.cnblogs.com/phinecos/archive/2009/05/03/1448121.html -
// http://www.brucelindbloom.com/index.html?Eqn_RGB_XYZ_Matrix.html -
// http://www.programmershare.com/1288015/ -
// http://blog.sina.com.cn/s/blog_6806030c0101ei9z.html -
#include -
template -
const T& HYMin(const T& refT1, const T& refT2) -
{ -
return (refT1 < refT2) ? refT1 : refT2; -
} -
template -
const T& HYMax(const T& refT1, const T& refT2) -
{ -
return (refT1 > refT2) ? refT1 : refT2; -
} -
// RGB转换为YUV -
void RGB2YUV(double dR, double dG, double dB, double &dY, double &dU, double &dV) -
{ -
dY = 0.257 * dR + 0.504 * dG + 0.098 * dB + 16; // y -
dU = -0.148 * dR - 0.291 * dG + 0.439 * dB + 128; // u -
dV = 0.439 * dR - 0.368 * dG - 0.071 * dB + 128; // v -
} -
// YUV转换为RGB -
void YUV2RGB(double dY, double dU, double dV, double &dR, double &dG, double &dB) -
{ -
dR = 1.0 * dY + 8 + 1.402 * (dV - 128); -
dG = 1.0 * dY - 0.34413 * (dU - 128) - 0.71414 * (dV - 128); -
dB = 1.0 * dY + 1.772 * (dU - 128) + 0; -
} -
// RGB转换为XYZ -
void RGB2XYZ(double dR, double dG, double dB, double &dX, double &dY, double &dZ) -
{ -
double dTempR = (dR / 255.0); -
double dTempG = (dG / 255.0); -
double dTempB = (dB / 255.0); -
if(0.04045 < dTempR) -
{ -
dTempR = pow((dTempR + 0.055) / 1.055, 2.4); -
} -
else -
{ -
dTempR /= 12.92; -
} -
if(0.04045 < dTempG) -
{ -
dTempG = pow((dTempG + 0.055) / 1.055, 2.4); -
} -
else -
{ -
dTempG /= 12.92; -
} -
if(0.04045 < dTempB) -
{ -
dTempB = pow((dTempB + 0.055) / 1.055, 2.4); -
} -
else -
{ -
dTempB /= 12.92; -
} -
dTempR *= 100.0; -
dTempG *= 100.0; -
dTempB *= 100.0; -
//Observer. = 2°, Illuminant = D65 -
dX = 0.4124564 * dTempR + 0.3575761 * dTempG + 0.1804375 * dTempB; -
dY = 0.2126729 * dTempR + 0.7151522 * dTempG + 0.0721750 * dTempB; -
dZ = 0.0193339 * dTempR + 0.1191920 * dTempG + 0.9503041 * dTempB; -
} -
// XYZ转换为LAB -
void XYZ2LAB(double dX, double dY, double dZ, double &dL, double &dA ,double &dB) -
{ -
double dTempX = dX / 95.047; -
double dTempY = dY / 100.000; -
double dTempZ = dZ / 108.883; -
if(0.008856 < dTempX) -
{ -
dTempX = pow((float)dTempX, 1.0f / 3.0f); -
} -
else -
{ -
dTempX = ( 7.787 * dTempX ) + (16.0 / 116.0); -
} -
if(0.008856 < dTempY) -
{ -
dTempY = pow((float)dTempY, 1.0f / 3.0f); -
} -
else -
{ -
dTempY = (7.787 * dTempY) + (16.0 / 116.0); -
} -
if(0.008856 < dTempZ) -
{ -
dTempZ = pow((float)dTempZ, 1.0f / 3.0f); -
} -
else -
{ -
dTempZ = (7.787 * dTempZ) + (16.0 / 116.0); -
} -
dL = (116 * dTempY) - 16; -
dA = 500 * (dTempX - dTempY); -
dB = 200 * (dTempY - dTempZ); -
} -
// RGB转换为LAB -
void RGB2LAB(double dR, double dG, double dB, double &dLAB_L, double &dLAB_A, double &dLAB_B) -
{ -
double dX, dY, dZ; -
RGB2XYZ(dR, dG, dB, dX, dY, dZ); -
XYZ2LAB(dX, dY, dZ, dLAB_L, dLAB_A, dLAB_B); -
} -
// LAB转换为XYZ -
void LAB2XYZ(double dLAB_L, double dLAB_A, double dLAB_B, double &dX, double &dY, double &dZ) -
{ -
double dTempY = (dLAB_L + 16) / 116; -
double dTempX = dLAB_A / 500 + dTempY; -
double dTempZ = dTempY - dLAB_B / 200; -
if(pow((double)dTempY, 3) > 0.008856) -
{ -
dTempY = pow((double)dTempY, 3); -
} -
else -
{ -
dTempY = (dTempY - 16 / 116) / 7.787; -
} -
if(pow((double)dTempX, 3) > 0.008856) -
{ -
dTempX = pow((double)dTempX, 3); -
} -
else -
{ -
dTempX = (dTempX - 16 / 116) / 7.787; -
} -
if(pow((double)dTempZ, 3) > 0.008856) -
{ -
dTempZ = pow((double)dTempZ, 3); -
} -
else -
{ -
dTempZ = (dTempZ - 16.0 / 116.0) / 7.787; -
} -
dX = 95.047 * dTempX; -
dY = 100.000 * dTempY; -
dZ = 108.883 * dTempZ; -
} -
// XYZ转换为RGB -
void XYZ2RGB(double dX, double dY, double dZ, double &dR, double &dG, double &dB) -
{ -
double dTempX = dX / 100.0f; // X from 0 to 95.047 (Observer = 2°, Illuminant = D65) -
double dTempY = dY / 100.0f; // Y from 0 to 100.000 -
double dTempZ = dZ / 100.0f; // Z from 0 to 108.883 -
double dTempR = dTempX * 3.2404542 + dTempY * -1.5371385 + dTempZ * -0.4985314; -
double dTempG = dTempX * -0.9692660 + dTempY * 1.8760108 + dTempZ * 0.0415560; -
double dTempB = dTempX * 0.0556434 + dTempY * -0.2040259 + dTempZ * 1.0572252; -
if(0.0031308 < dTempR) -
{ -
dTempR = 1.055 * (pow(dTempR, (1 / 2.4))) - 0.055; -
} -
else -
{ -
dTempR *= 12.92; -
} -
if(0.0031308 < dTempG) -
{ -
dTempG = 1.055 * (pow(dTempG, (1 / 2.4))) - 0.055; -
} -
else -
{ -
dTempG *= 12.92; -
} -
if(0.0031308 < dTempB) -
{ -
dTempB = 1.055 * (pow(dTempB, (1 / 2.4))) - 0.055; -
} -
else -
{ -
dTempB *= 12.92; -
} -
dR = 255.0f * dTempR; -
dG = 255.0f * dTempG; -
dB = 255.0f * dTempB; -
} -
// LAB转换为RGB -
void LAB2RGB(double dLAB_L, double dLAB_A, double dLAB_B, double &dR, double &dG, double &dB) -
{ -
double dX, dY, dZ; -
LAB2XYZ(dLAB_L, dLAB_A, dLAB_B, dX, dY, dZ); -
XYZ2RGB(dX, dY, dZ, dR, dG, dB); -
} -
// RGB转换为HSV -
void RGB2HSV(double dR, double dG, double dB, double &dH, double &dS, double& dV) -
{ -
double dTempR = (dR / 255); // RGB from 0 to 255 -
double dTempG = (dG / 255); -
double dTempB = (dB / 255); -
double dMin, dMax, dDelMax; -
dMin = HYMin(HYMin(dTempR, dTempG), dTempB); -
dMax = HYMax(HYMax(dTempR, dTempG), dTempB); -
dDelMax = dMax - dMin; // Delta RGB value -
dV = dMax; -
if(0 == dMax) // This is a gray, no chroma -
{ -
dH = 0.0; // HSV results from 0 to 1 -
dS = 0.0; -
} -
else // Chromatic data -
{ -
dS = dDelMax / dMax; -
double dDelR = (((dMax - dTempR) / 6) + (dDelMax / 2)) / dDelMax; -
double dDelG = (((dMax - dTempG) / 6) + (dDelMax / 2)) / dDelMax; -
double dDelB = (((dMax - dTempB) / 6) + (dDelMax / 2)) / dDelMax; -
if(dTempR == dMax) -
{ -
dH = dDelB - dDelG; -
} -
else if(dTempG == dMax) -
{ -
dH = (1.0 / 3.0) + dDelR - dDelB; -
} -
else if(dTempB == dMax) -
{ -
dH = (2.0 / 3.0) + dDelG - dDelR; -
} -
if(0 > dH) -
{ -
dH += 1.0; -
} -
if(1 < dH) -
{ -
dH -= 1.0; -
} -
} -
} -
// HSV转换为RGB -
void HSV2RGB(double dH, double dS, double dV, double &dR, double &dG, double &dB) -
{ -
if(dS == 0) // HSV from 0 to 1 -
{ -
dR = 255.0f * dV; -
dG = 255.0f * dV; -
dB = 255.0f * dV; -
} -
else -
{ -
// 86912219 -
double dTempH, dTempI, dTemp1, dTemp2, dTemp3; -
dTempH = 6.0f * dH; -
if(6 == dTempH) -
{ -
dTempH = 0.0; // H must be < 1 -
} -
dTempI = int(dTempH); //Or var_i = floor( var_h ) -
dTemp1 = dV * (1 - dS); -
dTemp2 = dV * (1 - dS * (dTempH - dTempI)); -
dTemp3 = dV * (1 - dS * (1 - (dTempH - dTempI))); -
double dTempR, dTempG, dTempB; -
if(0 == dTempI) -
{ -
dTempR = dV; -
dTempG = dTemp3 ; -
dTempB = dTemp1; -
} -
else if(1 == dTempI) -
{ -
dTempR = dTemp2 ; -
dTempG = dV; -
dTempB = dTemp1; -
} -
else if(2 == dTempI) -
{ -
dTempR = dTemp1; -
dTempG = dV; -
dTempB = dTemp3; -
} -
else if (3 == dTempI) -
{ -
dTempR = dTemp1 ; -
dTempG = dTemp2 ; -
dTempB = dV; -
} -
else if(4 == dTempI) -
{ -
dTempR = dTemp3; -
dTempG = dTemp1; -
dTempB = dV; -
} -
else -
{ -
dTempR = dV; -
dTempG = dTemp1; -
dTempB = dTemp2; -
} -
dR = 255.0f * dTempR; // RGB results from 0 to 255 -
dG = 255.0f * dTempR; -
dB = 255.0f * dTempR; -
} -
} -
// YUV转换为XYZ -
void YUV2XYZ(double dL, double dU, double dV, double &dX, double &dY, double &dZ) -
{ -
double dTempY, dRefX, dRefY, dRefZ, dRefU, dRefV, dTempU, dTempV; -
dTempY = (dL + 16) / 116; -
if(pow(dTempY, 3) > 0.008856) -
{ -
dTempY = pow(dTempY, 3); -
} -
else -
{ -
dTempY = (dTempY - 16.0 / 116.0) / 7.787; -
} -
dRefX = 95.047; //Observer= 2°, Illuminant= D65 -
dRefY = 100.000; -
dRefZ = 108.883; -
dRefU = (4 * dRefX ) / (dRefX + (15 * dRefY) + (3 * dRefZ)); -
dRefV = (9 * dRefY ) / (dRefX + (15 * dRefY) + (3 * dRefZ)); -
dTempU = dU / (13 * dL) + dRefU; -
dTempV = dV / (13 * dL) + dRefV; -
dY = dTempY * 100; -
dX = -(9 * dY * dTempU) / ((dTempU - 4) * dTempV - dTempU * dTempV); -
dZ = (9 * dY - (15 * dTempV * dY) - (dTempV * dX)) / (3 * dTempV); -
} -
// XYZ转换为HSV -
void XYZ2HSV(double dX, double dY, double dZ,double &dH, double &dS, double &dV) -
{ -
double dR, dG, dB; -
XYZ2RGB(dX, dY, dZ, dR, dG, dB); -
RGB2HSV(dR, dG, dB, dH, dS, dV); -
} -
// LAB转换为HSV -
void LAB2HSV(double dL, double dA, double dB, double &dH, double &dS, double &dV) -
{ -
double dX, dY, dZ; -
LAB2XYZ(dL, dA, dB, dX, dY, dZ); -
XYZ2HSV(dX, dY, dZ, dH, dS, dV); -
} -
// RGB转换为CMY -
void RGB2CMY(double dR, double dG, double dB, double &dC, double &dM, double dY) -
{ -
dC = 1.0 - (dR / 255.0f); -
dM = 1.0 - (dG / 255.0f); -
dY = 1.0 - (dB / 255.0f); -
} -
//CMY转换为RGB -
void CMY2RGB(double dC, double dM, double dY, double &dR, double &dG, double &dB) -
{ -
dR = (1.0f - dC) * 255.0f; -
dG = (1.0f - dM) * 255.0f; -
dB = (1.0f - dY) * 255.0f; -
} -
//RGB转换为CMYK -
void RGB2CMYK(double dR, double dG, double dB, double &dC, double &dM, double dY, double &dK) -
{ -
// RGB2CMY -
RGB2CMY(dR, dG, dB, dC, dM, dY); -
//CMYK and CMY values from 0 to 1 -
double dTempK = 1.0; -
if(dC < dTempK) -
{ -
dTempK = dC; -
} -
if(dM < dTempK) -
{ -
dTempK = dM; -
} -
if(dY < dTempK) -
{ -
dTempK = dY; -
} -
if(1 == dTempK) -
{ //Black -
dC = 0; -
dM = 0; -
dY = 0; -
} -
else -
{ -
dC = (dC - dTempK) / (1 - dTempK); -
dM = (dM - dTempK) / (1 - dTempK); -
dY = (dY - dTempK) / (1 - dTempK); -
} -
dK = dTempK; -
} -
// CMYK转换为CMY -
void CMYK2CMY(double dC1, double dM1, double dY1, double dK1, double &dC2, double &dM2, double dY2) -
{ -
dC2 = (dC1 * (1 - dK1) + dK1); -
dM2 = (dM1 * (1 - dK1) + dK1); -
dY2 = (dY1 * (1 - dK1) + dK1); -
}
// RGBHSL互转描述, 我已验证, 这个就是Windows颜色选择对话框的颜色选择转换算法
http://www.cnblogs.com/daiguagua/p/3311756.html
