IamOverlord
جمعه 03 مرداد 1393, 13:31 عصر
سلام دوستان!
یه کدی رو به ++C نوشتم (در اصل تبدیل کردم...) که برای تبدیل RGB به CIELab هست و برعکس... اما خطا داره! مثلا RGB 220,60,100 رو تبدیل می کنه به CIELab 53.8048 66.4264 15.4166 و بعد این رو تبدیل می کنه به RGB 232 63 105...
می خواستم بدونم کسی یه نسخه ی بهترش رو داره؟!
void RGB2Lab (unsigned char R, unsigned char G, unsigned char B, double* L, double* a, double* b){
double var_R = ( (double)R / 255 ); //R from 0 to 255
double var_G = ( (double)G / 255 ); //G from 0 to 255
double var_B = ( (double)B / 255 ); //B from 0 to 255
if ( var_R > 0.04045 ) var_R = pow ( var_R + 0.055 / 1.055 , 2.4);
else var_R = var_R / 12.92;
if ( var_G > 0.04045 ) var_G = pow ( var_G + 0.055 / 1.055 , 2.4);
else var_G = var_G / 12.92;
if ( var_B > 0.04045 ) var_B = pow ( var_B + 0.055 / 1.055 , 2.4);
else var_B = var_B / 12.92;
var_R = var_R * 100;
var_G = var_G * 100;
var_B = var_B * 100;
//Observer. = 2°, Illuminant = D65
double X = var_R * 0.4124 + var_G * 0.3576 + var_B * 0.1805;
double Y = var_R * 0.2126 + var_G * 0.7152 + var_B * 0.0722;
double Z = var_R * 0.0193 + var_G * 0.1192 + var_B * 0.9505;
double ref_X = 95.047;
double ref_Y = 100;
double ref_Z = 108.833;
double var_X = X / ref_X; //ref_X = 95.047 Observer= 2°, Illuminant= D65
double var_Y = Y / ref_Y; //ref_Y = 100.000
double var_Z = Z / ref_Z; //ref_Z = 108.883
if ( var_X > 0.008856 ) var_X = pow(var_X , 1.0/3.0 );
else var_X = ( 7.787 * var_X ) + ( 16.0 / 116.0 );
if ( var_Y > 0.008856 ) var_Y = pow(var_Y , 1.0/3.0 );
else var_Y = ( 7.787 * var_Y ) + ( 16.0 / 116.0 );
if ( var_Z > 0.008856 ) var_Z = pow(var_Z , 1.0/3.0 );
else var_Z = ( 7.787 * var_Z ) + ( 16.0 / 116.0 );
*L = ( 116 * var_Y ) - 16;
*a = 500 * ( var_X - var_Y );
*b = 200 * ( var_Y - var_Z );
}
void Lab2RGB (double L, double a, double b, unsigned char* R, unsigned char* G, unsigned char* B)
{
double var_Y = ( L + 16 ) / 116;
double var_X = a / 500 + var_Y;
double var_Z = var_Y - b / 200;
if ( pow(var_Y, 3) > 0.008856 ) var_Y = pow(var_Y, 3);
else var_Y = ( var_Y - 16 / 116 ) / 7.787;
if ( pow(var_X, 3) > 0.008856 ) var_X = pow(var_X, 3);
else var_X = ( var_X - 16 / 116 ) / 7.787;
if ( pow(var_Z, 3) > 0.008856 ) var_Z = pow(var_Z, 3);
else var_Z = ( var_Z - 16 / 116 ) / 7.787;
double ref_X = 95.047;
double ref_Y = 100;
double ref_Z = 108.833;
double X = ref_X * var_X; //ref_X = 95.047 Observer= 2°, Illuminant= D65
double Y = ref_Y * var_Y; //ref_Y = 100.000
double Z = ref_Z * var_Z; //ref_Z = 108.883
var_X = X / 100; //X from 0 to 95.047 (Observer = 2°, Illuminant = D65)
var_Y = Y / 100; //Y from 0 to 100.000
var_Z = Z / 100; //Z from 0 to 108.883
double var_R = var_X * 3.2406 + var_Y * -1.5372 + var_Z * -0.4986;
double var_G = var_X * -0.9689 + var_Y * 1.8758 + var_Z * 0.0415;
double var_B = var_X * 0.0557 + var_Y * -0.2040 + var_Z * 1.0570;
if ( var_R > 0.0031308 ) var_R = 1.055 * pow( var_R , 1 / 2.4 ) - 0.055;
else var_R = 12.92 * var_R;
if ( var_G > 0.0031308 ) var_G = 1.055 * pow( var_G , 1 / 2.4 ) - 0.055;
else var_G = 12.92 * var_G;
if ( var_B > 0.0031308 ) var_B = 1.055 * pow( var_B , 1 / 2.4 ) - 0.055;
else var_B = 12.92 * var_B;
*R =(unsigned char) (var_R * 255);
*G =(unsigned char) (var_G * 255);
*B =(unsigned char) (var_B * 255);
}
یه کدی رو به ++C نوشتم (در اصل تبدیل کردم...) که برای تبدیل RGB به CIELab هست و برعکس... اما خطا داره! مثلا RGB 220,60,100 رو تبدیل می کنه به CIELab 53.8048 66.4264 15.4166 و بعد این رو تبدیل می کنه به RGB 232 63 105...
می خواستم بدونم کسی یه نسخه ی بهترش رو داره؟!
void RGB2Lab (unsigned char R, unsigned char G, unsigned char B, double* L, double* a, double* b){
double var_R = ( (double)R / 255 ); //R from 0 to 255
double var_G = ( (double)G / 255 ); //G from 0 to 255
double var_B = ( (double)B / 255 ); //B from 0 to 255
if ( var_R > 0.04045 ) var_R = pow ( var_R + 0.055 / 1.055 , 2.4);
else var_R = var_R / 12.92;
if ( var_G > 0.04045 ) var_G = pow ( var_G + 0.055 / 1.055 , 2.4);
else var_G = var_G / 12.92;
if ( var_B > 0.04045 ) var_B = pow ( var_B + 0.055 / 1.055 , 2.4);
else var_B = var_B / 12.92;
var_R = var_R * 100;
var_G = var_G * 100;
var_B = var_B * 100;
//Observer. = 2°, Illuminant = D65
double X = var_R * 0.4124 + var_G * 0.3576 + var_B * 0.1805;
double Y = var_R * 0.2126 + var_G * 0.7152 + var_B * 0.0722;
double Z = var_R * 0.0193 + var_G * 0.1192 + var_B * 0.9505;
double ref_X = 95.047;
double ref_Y = 100;
double ref_Z = 108.833;
double var_X = X / ref_X; //ref_X = 95.047 Observer= 2°, Illuminant= D65
double var_Y = Y / ref_Y; //ref_Y = 100.000
double var_Z = Z / ref_Z; //ref_Z = 108.883
if ( var_X > 0.008856 ) var_X = pow(var_X , 1.0/3.0 );
else var_X = ( 7.787 * var_X ) + ( 16.0 / 116.0 );
if ( var_Y > 0.008856 ) var_Y = pow(var_Y , 1.0/3.0 );
else var_Y = ( 7.787 * var_Y ) + ( 16.0 / 116.0 );
if ( var_Z > 0.008856 ) var_Z = pow(var_Z , 1.0/3.0 );
else var_Z = ( 7.787 * var_Z ) + ( 16.0 / 116.0 );
*L = ( 116 * var_Y ) - 16;
*a = 500 * ( var_X - var_Y );
*b = 200 * ( var_Y - var_Z );
}
void Lab2RGB (double L, double a, double b, unsigned char* R, unsigned char* G, unsigned char* B)
{
double var_Y = ( L + 16 ) / 116;
double var_X = a / 500 + var_Y;
double var_Z = var_Y - b / 200;
if ( pow(var_Y, 3) > 0.008856 ) var_Y = pow(var_Y, 3);
else var_Y = ( var_Y - 16 / 116 ) / 7.787;
if ( pow(var_X, 3) > 0.008856 ) var_X = pow(var_X, 3);
else var_X = ( var_X - 16 / 116 ) / 7.787;
if ( pow(var_Z, 3) > 0.008856 ) var_Z = pow(var_Z, 3);
else var_Z = ( var_Z - 16 / 116 ) / 7.787;
double ref_X = 95.047;
double ref_Y = 100;
double ref_Z = 108.833;
double X = ref_X * var_X; //ref_X = 95.047 Observer= 2°, Illuminant= D65
double Y = ref_Y * var_Y; //ref_Y = 100.000
double Z = ref_Z * var_Z; //ref_Z = 108.883
var_X = X / 100; //X from 0 to 95.047 (Observer = 2°, Illuminant = D65)
var_Y = Y / 100; //Y from 0 to 100.000
var_Z = Z / 100; //Z from 0 to 108.883
double var_R = var_X * 3.2406 + var_Y * -1.5372 + var_Z * -0.4986;
double var_G = var_X * -0.9689 + var_Y * 1.8758 + var_Z * 0.0415;
double var_B = var_X * 0.0557 + var_Y * -0.2040 + var_Z * 1.0570;
if ( var_R > 0.0031308 ) var_R = 1.055 * pow( var_R , 1 / 2.4 ) - 0.055;
else var_R = 12.92 * var_R;
if ( var_G > 0.0031308 ) var_G = 1.055 * pow( var_G , 1 / 2.4 ) - 0.055;
else var_G = 12.92 * var_G;
if ( var_B > 0.0031308 ) var_B = 1.055 * pow( var_B , 1 / 2.4 ) - 0.055;
else var_B = 12.92 * var_B;
*R =(unsigned char) (var_R * 255);
*G =(unsigned char) (var_G * 255);
*B =(unsigned char) (var_B * 255);
}