在使用旧PC 1 时,我发现了一些我认为是奇怪的渲染错误的东西。
当颜色深度设置为16位(32768色)时,会出现问题。
特别是,当使用Graphics2D
绘制具有低alpha值的颜色时,它会显示出来。以下是重现该问题的MVCE。它只绘制几组线条,颜色为白色,其alpha值范围为4到12.运行此程序的结果显示在以下屏幕截图中:
可以看到一些颜色实际上是绿色的某些alpha值,但显然应该 50 9灰度。
(同样,它仅在颜色深度设置为16位时出现!)
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
public class _WTFPaintTest
{
public static void main(String[] args)
{
SwingUtilities.invokeLater(new Runnable()
{
@Override
public void run()
{
createAndShowGUI();
}
});
}
private static void createAndShowGUI()
{
JFrame f = new JFrame();
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.getContentPane().add(new JPanel()
{
@Override
protected void paintComponent(Graphics gr)
{
super.paintComponent(gr);
Graphics2D g = (Graphics2D)gr;
g.setColor(Color.BLACK);
g.fillRect(0,0,getWidth(),getHeight());
for (int a=4; a<=12; a++)
{
int x = (a-3) * 50;
g.setColor(Color.WHITE);
g.drawString(String.valueOf(a), x, 25);
g.setColor(new Color(255,255,255,a));
for (int j=0; j<3; j++)
{
for (int i=0; i<50; i++)
{
g.drawLine(x,50+i,x+25,75);
}
}
}
}
});
f.setSize(550,200);
f.setLocationRelativeTo(null);
f.setVisible(true);
}
}
(我在这里用它的原名发布,以强调我发现这有多刺激......)
在这种情况下,奇数色彩渲染的原因是什么?
1 :WinXP,32位,NVIDIA GeForce 2显卡
答案 0 :(得分:3)
此行为的原因是颜色组件(红色,绿色和蓝色)在16-bit color mode中用不同的位数表示。
16位分布在颜色分量中,如下所示:
这意味着16位颜色具有2 5 = 32种不同的红色和蓝色,但是2 6 = 64种绿色阴影。
(绿色接收额外的位,因为对于绿色阴影,人眼的灵敏度比红色或蓝色阴影更大)
现在,当标准24 bit RGB color转换为16位颜色时,将发生采样错误。在24位颜色中,每个颜色分量具有8位。通过获取颜色分量的最高位,将它们转换为16位颜色的相应分量。
在示例屏幕截图中,可以看到用alpha值为7绘制的线条。此颜色的RGB表示形式为(7,7,7)。该颜色的二进制表示为(00000111 b ,00000111 b ,00000111 b )。当为每个颜色分量取最高位时,结果为
绿色组件因此是唯一具有非零值的组件。然后,屏幕上显示的实际颜色的绿色分量可以想象为6位绿色分量,左移2位:
通过检查屏幕截图中的相应像素来确认这一点,这些像素存储为0x000C00
或24位RGB值(0,12,0):深绿色阴影。