【发布时间】:2015-07-14 12:22:07
【问题描述】:
我正在尝试一些算法来编写一种从颜色中删除 alpha 值并给出相同 rgb 值的方法,但似乎我的测试总是失败。我相信它被称为阿尔法混合?我不确定。这是我用于转换的算法。
public static int removeAlpha(int foreground, int background) {
int redForeground = Color.red(foreground);
int redBackground = Color.red(background);
int greenForeground = Color.green(foreground);
int greenBackground = Color.green(background);
int blueForeground = Color.blue(foreground);
int blueBackground = Color.blue(background);
int alphaForeground = Color.alpha(foreground);
int redNew = (redForeground * alphaForeground) + (redBackground * (1 - alphaForeground));
int greenNew = (greenForeground * alphaForeground) + (greenBackground * (1 - alphaForeground));
int blueNew = (blueForeground * alphaForeground) + (blueBackground * (1 - alphaForeground));
return Color.rgb(redNew, greenNew, blueNew);
}
还有这样的测试
@Test
public void removeAlpha() {
int red = Color.RED;
Assert.assertEquals(0xFFFF7F7F, Heatmap.removeAlpha(red, 0xFFFFFFFF));
}
junit.framework.AssertionFailedError:
Expected :-32897
Actual :-258
当我在 Photoshop 中绘制红色并将不透明度设置为 50% 时,它给了我 255,127,127 rgb,这似乎与 50% 不透明的纯红色相同。我认为那里的算法是错误的。任何帮助将不胜感激。
编辑:这是模拟颜色:
PowerMockito.mockStatic(Color.class);
PowerMockito.when(Color.rgb(Mockito.anyInt(), Mockito.anyInt(), Mockito.anyInt())).thenAnswer(new Answer<Object>() {
@Override
public Object answer(InvocationOnMock invocation) throws Throwable {
int red = (int) invocation.getArguments()[0];
int green = (int) invocation.getArguments()[1];
int blue = (int) invocation.getArguments()[2];
return (0xFF << 24) | (red << 16) | (green << 8) | blue;
}
});
PowerMockito.when(Color.alpha(Mockito.anyInt())).thenAnswer(new Answer<Object>() {
@Override
public Object answer(InvocationOnMock invocation) throws Throwable {
return ((int)invocation.getArguments()[0])>>>24;
}
});
PowerMockito.when(Color.red(Mockito.anyInt())).thenAnswer(new Answer<Object>() {
@Override
public Object answer(InvocationOnMock invocation) throws Throwable {
return (((int)invocation.getArguments()[0])>>16) & 0xFF;
}
});
PowerMockito.when(Color.green(Mockito.anyInt())).thenAnswer(new Answer<Object>() {
@Override
public Object answer(InvocationOnMock invocation) throws Throwable {
return (((int)invocation.getArguments()[0])>>8) & 0XFF;
}
});
PowerMockito.when(Color.blue(Mockito.anyInt())).thenAnswer(new Answer<Object>() {
@Override
public Object answer(InvocationOnMock invocation) throws Throwable {
return (int)invocation.getArguments()[0] & 0xFF;
}
});
【问题讨论】:
-
哦忘了提到我嘲笑了 Color 静态类,但这并不重要。我只是嘲笑他们,因为junit不会让我不嘲笑他们。我只是使用了它们的源代码,所以它们工作正常。
-
您的公式似乎是正确的。然而,我认识到你忽略了
alphaBackground。但这不是问题,因为您的测试用例将此属性设置为 100%。 -
您将颜色值视为
[0, 1]之间的范围。您的Color.xx函数是否有可能返回[0, 255]的值? -
@maja 是的,那是因为我认为背景颜色将始终完全不透明,以免使事情复杂化。
-
尝试用
255-替换公式中的1-