Java 以16位颜色深度在图形2D中绘制时颜色错误
在使用旧的PC1时,我发现了一些我认为是奇怪的渲染错误 当颜色深度设置为16位(32768种颜色)时,会出现问题 特别是,当使用Java 以16位颜色深度在图形2D中绘制时颜色错误,java,colors,alpha,graphics2d,Java,Colors,Alpha,Graphics2d,在使用旧的PC1时,我发现了一些我认为是奇怪的渲染错误 当颜色深度设置为16位(32768种颜色)时,会出现问题 特别是,当使用Graphics2D绘制低alpha值的颜色时,它会显示出来。以下是重现该问题的示例。它只绘制了几组线,带有一种白色颜色,其alpha值范围为4到12。运行此程序的结果显示在以下屏幕截图中: 我们可以看到,对于某些alpha值,有些颜色实际上是绿色的,尽管显然应该有50 9个灰度 (同样,它仅在颜色深度设置为16位时显示!) 导入java.awt.Color; 导入j
Graphics2D
绘制低alpha值的颜色时,它会显示出来。以下是重现该问题的示例。它只绘制了几组线,带有一种白色颜色,其alpha值范围为4到12。运行此程序的结果显示在以下屏幕截图中:
我们可以看到,对于某些alpha值,有些颜色实际上是绿色的,尽管显然应该有50 9个灰度
(同样,它仅在颜色深度设置为16位时显示!)
导入java.awt.Color;
导入java.awt.Graphics;
导入java.awt.Graphics2D;
导入javax.swing.JFrame;
导入javax.swing.JPanel;
导入javax.swing.SwingUtilities;
公共类油漆测试
{
公共静态void main(字符串[]args)
{
SwingUtilities.invokeLater(新的Runnable()
{
@凌驾
公开募捐
{
createAndShowGUI();
}
});
}
私有静态void createAndShowGUI()
{
JFrame f=新的JFrame();
f、 setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f、 getContentPane().add(新的JPanel())
{
@凌驾
受保护的组件(图形组)
{
超级油漆组件(gr);
Graphics2D g=(Graphics2D)gr;
g、 设置颜色(颜色为黑色);
g、 fillRect(0,0,getWidth(),getHeight());
对于(int a=4;a而言,此行为的原因是颜色组件(红色、绿色和蓝色)在中用不同数量的位表示
16位按如下方式分布在颜色分量中:
- 红色用5位表示
- 绿色用6位表示
- 蓝色用5位表示
这意味着16位颜色有25=32种不同的红色和蓝色,但26=64种绿色
(绿色接收附加位,因为人眼对绿色的敏感度大于红色或蓝色)
现在,当标准转换为16位颜色时,将发生采样错误。在24位颜色中,每个颜色分量有8位。通过获取颜色分量的最高阶位,这些值将转换为16位颜色的对应分量
在示例屏幕截图中,可以看到绘制的线的alpha值为7。此颜色的RGB表示为(7,7,7)。此颜色的二进制表示为(00000 111b,00000 111b,00000 111b)。当为每个颜色分量获取最高阶位时,结果为
- 红色的5位:00000111b->00000b
- 绿色6位:00000111b->000001b
- 5位蓝色:00000111b->00000b
因此,绿色分量是唯一具有非零值的分量。然后显示在屏幕上的实际颜色的绿色分量可以想象为6位绿色分量,左移2位:
- 000001b此行为的原因是颜色组件(红色、绿色和蓝色)在中用不同的位数表示
16位按如下方式分布在颜色分量中:
- 红色用5位表示
- 绿色用6位表示
- 蓝色用5位表示
这意味着16位颜色有25=32种不同的红色和蓝色,但26=64种绿色
(绿色接收附加位,因为人眼对绿色的敏感度大于红色或蓝色)
现在,当标准转换为16位颜色时,将发生采样错误。在24位颜色中,每个颜色分量有8位。通过获取颜色分量的最高阶位,这些值将转换为16位颜色的对应分量
在示例屏幕截图中,可以看到绘制的线的alpha值为7。此颜色的RGB表示为(7,7,7)。此颜色的二进制表示为(00000 111b,00000 111b,00000 111b)。当为每个颜色分量获取最高阶位时,结果为
- 红色的5位:00000111b->00000b
- 绿色6位:00000111b->000001b
- 5位蓝色:00000111b->00000b
因此,绿色分量是唯一具有非零值的分量。然后显示在屏幕上的实际颜色的绿色分量可以想象为6位绿色分量,左移2位:
- 这是一个很好的解释!坚持下去!(至于我自己,我知道这件事,但不能写这么好的答案,真的很好!)这是一个很好的解释!坚持下去!(至于我自己,我知道这件事,但不能写这么好的答案,真的很好!)
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);
}
}