2

I am trying to create Brightness and Contrast filters similar to new Adobe Photoshop or Lightroom Brightness and Contrast filters. I am doing RGB -> XYZ - xyY conversion and with increasing pixel Brightness (Y) ( not linear increase, Brightness increase is calculated depending on pixels Brightness) and then converting back to XYZ and RGB trying to get as similar as possible values to test image that I used to increase Brightness in Adobe. I am not getting similar results as I think I am missing something, maybe gamma calculation or as images are in sRGB space some color space conversion, or I simple have bug in Color conversion code? So here are Color conversion function I used (in Objective-C) :

-(void) convertRGBcolor:(cColorRGB*) pRGB toXYZcolor:(zColorXYZ*) pXYZ
{
    if(pRGB == nil || pXYZ == nil) {
        return;
    }

    double var_R = ( pRGB->r / 255.0 );
    double var_G = ( pRGB->g / 255.0 );
    double var_B = ( pRGB->b / 255.0 );

    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
    pXYZ->X = var_R * 0.4124 + var_G * 0.3576 + var_B * 0.1805;
    pXYZ->Y = var_R * 0.2126 + var_G * 0.7152 + var_B * 0.0722;
    pXYZ->Z = var_R * 0.0193 + var_G * 0.1192 + var_B * 0.9505;
}

-(void) convertXYZcolor:(zColorXYZ*) pXYZ toRGBcolor:(cColorRGB*) pRGB
{
    if(pRGB == nil || pXYZ == nil) {
        return;
    }

    double var_X = pXYZ->X / 100;        //X from 0 to  95.047
    double var_Y = pXYZ->Y / 100;        //Y from 0 to 100.000
    double var_Z = pXYZ->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;

    pRGB->r = var_R * 255;
    pRGB->g = var_G * 255;
    pRGB->b = var_B * 255;
}

-(void) convertYxycolor:(zColorYxy*) pYxy toXYZcolor:(zColorXYZ*) pXYZ
{
    if(pYxy == nil || pXYZ == nil) {
        return;
    }

    pXYZ->X = pYxy->x * ( pYxy->Y / pYxy->y );
    pXYZ->Y = pYxy->Y;
    pXYZ->Z = ( 1 - pYxy->x - pYxy->y ) * ( pYxy->Y / pYxy->y );
}

-(void) convertXYZcolor:(zColorXYZ*) pXYZ toYxycolor:(zColorYxy*) pYxy
{
    if(pYxy == nil || pXYZ == nil) {
        return;
    }

    pYxy->Y = pXYZ->Y;
    pYxy->x = pXYZ->X / ( pXYZ->X + pXYZ->Y + pXYZ->Z );
    pYxy->y = pXYZ->Y / ( pXYZ->X + pXYZ->Y + pXYZ->Z );
}
4

0 回答 0