你如何平均将两个32位颜色打包成一个整数?

Mik*_*eir 3 int average colors

我试图平均两种颜色.

我原来的(可怕的)工具如下:

//color is a union
int ColorAverage(int c1, int c2) {
    color C1(c1);
    color C2(c2);
    return color(
        (unsigned char)(0.5f * C1.a + 0.5f * C2.a),
        (unsigned char)(0.5f * C1.r + 0.5f * C2.r),
        (unsigned char)(0.5f * C1.g + 0.5f * C2.g),
        (unsigned char)(0.5f * C1.b + 0.5f * C2.b)
    ).c;
}
Run Code Online (Sandbox Code Playgroud)

我目前的解决方案如下(表现更好):

int ColorAverage(int c1, int c2) {
    unsigned char* b1 = reinterpret_cast<unsigned char*>(&c1);
    unsigned char* b2 = reinterpret_cast<unsigned char*>(&c2);
    int value;
    unsigned char* bv = reinterpret_cast<unsigned char*>(&value);
    bv[0] = (b1[0] + b2[0]) / 2;
    bv[1] = (b1[1] + b2[1]) / 2;
    bv[2] = (b1[2] + b2[2]) / 2;
    bv[3] = (b1[3] + b2[3]) / 2;
    return(value);
}
Run Code Online (Sandbox Code Playgroud)

但是,它仍然很慢(大约是我帧时间的3%).

我确实找到了24位的解决方案,但它不适用于32位(alpha丢失):

#define AVERAGE(a, b)   ( ((((a) ^ (b)) & 0xfffefefeL) >> 1) + ((a) & (b)) )
Run Code Online (Sandbox Code Playgroud)

http://www.compuphase.com/graphic/scale3.htm#HSIEH1

das*_*ght 5

尝试将掩码扩展到32位,如下所示:

#define AVERAGE(a, b)   ( ((((a) ^ (b)) & 0xfefefefeL) >> 1) + ((a) & (b)) )
Run Code Online (Sandbox Code Playgroud)

编辑:我做了一个快速检查,它似乎适用于我的测试用例.漂亮的配方,顺便说一下!