如何正确混合两种 int 颜色

May*_*ius 5 java int bit-manipulation colors color-blending

我正在尝试混合两种编码为整数的颜色。这是我的小功能:

int blend (int a, int b, float ratio) {
    if (ratio > 1f) {
        ratio = 1f;
    } else if (ratio < 0f) {
        ratio = 0f;
    }
    float iRatio = 1.0f - ratio;

    int aA = (a >> 24 & 0xff);
    int aR = ((a & 0xff0000) >> 16);
    int aG = ((a & 0xff00) >> 8);
    int aB = (a & 0xff);

    int bA = (b >> 24 & 0xff);
    int bR = ((b & 0xff0000) >> 16);
    int bG = ((b & 0xff00) >> 8);
    int bB = (b & 0xff);

    int A = ((int)(aA * iRatio) + (int)(bA * ratio));
    int R = ((int)(aR * iRatio) + (int)(bR * ratio));
    int G = ((int)(aG * iRatio) + (int)(bG * ratio));
    int B = ((int)(aB * iRatio) + (int)(bB * ratio));

    return A << 24 | R << 16 | G << 8 | B;
}
Run Code Online (Sandbox Code Playgroud)

一切似乎都很好,但某些参数会产生错误的颜色。例如:

    int a = 0xbbccdd;
    int b = 0xbbccdd;
    int c = blend(a, b, 0.5f); // gives 0xbaccdc, although it should be 0xbbccdd
Run Code Online (Sandbox Code Playgroud)

我的猜测是,这里应该归咎于乘法浮动比率或强制转换,但我无法弄清楚它们有什么问题......

那么在java中混合两种颜色的正确方法是什么?

dAR*_*NCE 5

我的猜测是,转换为 int 应该在添加之后完成。像这样

int a = (int)((aA * iRatio) + (bA * ratio));
Run Code Online (Sandbox Code Playgroud)

我还建议在使用变量时使用 Java 命名约定。只有常量应该是大写的。


bma*_*ter 5

感谢 JuliusB 和 dARKpRINCE。我已经对其进行了调整以接受 java.awt.Color,修复了强制转换并将变量重命名为更像 Java 标准的变量。它运作良好。再次感谢!

Color blend( Color c1, Color c2, float ratio ) {
    if ( ratio > 1f ) ratio = 1f;
    else if ( ratio < 0f ) ratio = 0f;
    float iRatio = 1.0f - ratio;

    int i1 = c1.getRGB();
    int i2 = c2.getRGB();

    int a1 = (i1 >> 24 & 0xff);
    int r1 = ((i1 & 0xff0000) >> 16);
    int g1 = ((i1 & 0xff00) >> 8);
    int b1 = (i1 & 0xff);

    int a2 = (i2 >> 24 & 0xff);
    int r2 = ((i2 & 0xff0000) >> 16);
    int g2 = ((i2 & 0xff00) >> 8);
    int b2 = (i2 & 0xff);

    int a = (int)((a1 * iRatio) + (a2 * ratio));
    int r = (int)((r1 * iRatio) + (r2 * ratio));
    int g = (int)((g1 * iRatio) + (g2 * ratio));
    int b = (int)((b1 * iRatio) + (b2 * ratio));

    return new Color( a << 24 | r << 16 | g << 8 | b );
}
Run Code Online (Sandbox Code Playgroud)