Qt(C ++)在32位浮点数和QRgba之间转换

时间:2016-02-16 01:28:59

标签: c++ qt4 qt5 rgb rgba

我正在尝试将此帖子中显示的代码(How do I convert a vec4 rgba value to a float?)移植到Qt(C ++)。我已粘贴下面的整个代码。我的结果不太准确。关于我做错了什么想法?

结果:

Input:  -10.01
Sign:  1  F:  10  Sign:  1  Exponent:  130  Mantissa:  1.25
Red:  193  Green:  32  Blue:  0  Alpha:  0
Result:  -10.0151 

Input:  -1
Sign:  1  F:  1  Sign:  1  Exponent:  127  Mantissa:  1
Red:  191  Green:  128  Blue:  0  Alpha:  0
Result:  -1.00195 

Input:  5.3
Sign:  0  F:  5  Sign:  0  Exponent:  129  Mantissa:  1.25
Red:  64  Green:  160  Blue:  0  Alpha:  0
Result:  5.0116 

代码:

#include <QCoreApplication>
#include <math.h>
#include <QColor>
#include <QDebug>

float step(float edge, float x) {
    if ( x < edge ) {
        return 0.0;
    }
    else {
        return 1.0;
    }
}

QColor encode32(float f) {

    //float e = 5.0;
    qDebug() << "Input: " << f;
    float F = abs(f);
    float Sign = step(0.0,-f);
    float Exponent = floor(log2(F));
    float Mantissa = F/exp2(Exponent);
    if(Mantissa < 1)
        Exponent -= 1;
    Exponent +=  127;
    qDebug() << "Sign: " << Sign << " F: " << F << " Sign: " << Sign << " Exponent: " << Exponent << " Mantissa: " << Mantissa;
    float red = 128.0 * Sign  + floor(Exponent*exp2(-1.0));
    float green = 128.0 * fmod(Exponent,2.0) + fmod(floor(Mantissa*128.0),128.0);
    float blue = floor(fmod(floor(Mantissa*exp2(23.0 -8.0)),exp2(8.0)));
    float alpha = floor(exp2(23.0)*fmod(Mantissa,exp2(-15.0)));
    qDebug() << "Red: " << red << " Green: " << green << " Blue: " << blue << " Alpha: " << alpha;
    QColor rgba;
    rgba.setRed(red);
    rgba.setGreen(green);
    rgba.setBlue(blue);
    rgba.setAlpha(alpha);
    return rgba;

}

float decode32 (QColor rgba) {

    float red = rgba.redF() * 255.0;
    float green = rgba.greenF() * 255.0;
    float blue = rgba.blackF() * 255.0;
    float alpha = rgba.alphaF() * 255.0;

    float Sign = 1.0 - step(128.0,red)*2.0;
    float Exponent = 2.0 * fmod(red,128.0) + step(128.0,green) - 127.0;
    float Mantissa = fmod(green,128.0)*65536.0 + blue*256.0 + alpha + float(0x800000);
    float Result =  Sign * exp2(Exponent-23.0f) * Mantissa;
    return Result;
}

int main(int argc, char *argv[])
{

    QCoreApplication a(argc, argv);


    {
        float result;
        QColor rgba = encode32(-10.01);
        result = decode32(rgba);
        qDebug() << "Result: " << result << "\n";
    }

    {
        float result;
        QColor rgba = encode32(-1.0);
        result = decode32(rgba);
        qDebug() << "Result: " << result << "\n";
    }

    {
        float result;
        QColor rgba = encode32(5.3);
        result = decode32(rgba);
        qDebug() << "Result: " << result << "\n";
    }

    return a.exec();

}

1 个答案:

答案 0 :(得分:1)

这是不可能的,至少不是那种方法。浮点数有32位数据,但它必须表示NaN和无穷大之类的东西。因此,您实际上有少于32位来尝试存储您的rgba值,但它需要一个完整的32位(红色,绿色,蓝色,alpha各8位)。它无法完成,除非你将内存转移到一个无法达到目的的int。