使用JColorChooser时,输入的CMYK值会转换为特定的RGB颜色。在RGB端手动输入该颜色时,CMYK值 与以前不同。
以下程序可用于演示我遇到的行为。
import java.awt.*;
import javax.swing.*;
public class ColorChooserProblem {
JFrame f = new JFrame("Testing Color Chooser");
public static void main(String[] args) {
new ColorChooserProblem().start();
}
public void start() {
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JColorChooser jc1 = new JColorChooser();
JColorChooser jc2 = new JColorChooser();
f.add(jc1, BorderLayout.NORTH);
f.add(jc2, BorderLayout.SOUTH);
f.pack();
f.setLocationRelativeTo(null);
f.setVisible(true);
}
}
请注意,当以另一种方式使用(即首先选择RGB并重新输入CMYK值)时,所有操作均符合预期。我在想什么吗 对转换过程有什么期望,还是这是一个错误?
我正在Windows 10上运行Java 10,而我的IDE是Eclipse。
也发布在http://www.javaprogrammingforums.com/java-theory-questions/41836-possible-bug-jcolorchooser.html
答案 0 :(得分:4)
从一种(离散)颜色模型到另一种(离散)颜色模型的转换永远不可能是完美的。
从JColorChooser到CMYK到RGB到CMYK永远无法完美运行的原因仅仅是因为JColorChooser显示 integers 而不是浮点数。例如,在CMYK模型中选择yellow = 255,然后返回RGB。您将看到此黄色是红色= 255和绿色= 255的混合色。现在回到CMYK,将黄色降低为254并检查RGB值-它仍然是red = 255和green = 255!
现在将CMYK中的黄色更改为253,然后返回RGB。红色和绿色仍然是255,蓝色添加了值1。CMYK黄色= 254(以前的情况)的正确值可能是蓝色= 0.4,但是为了简化使用,仅在JColorChooser中显示整数,因此蓝色显示为0。
由于这些整数颜色模型的“颜色敏感度”不同,这一数字问题更加严重。 CMYK具有4个维度(青色,洋红色,黄色,键),因此可以表示256 ^ 4 = 4294967296不同的颜色RGB具有3个维度,并且只能表示256 ^ 3 = 16777216个颜色。因此,将CMYK转换为这种RGB时,您总是会丢失很多信息。
换句话说,平均而言,CMYK颜色空间中的256点仅由RGB颜色空间中的1点表示。当您将一种颜色从RGB转换回CMYK时,平均而言,CMYK空间中的255种颜色永远不会“达到”。
答案 1 :(得分:4)
我在JColorChooser
,尤其是ColorModelCMYK
(package-private类)使用的颜色模型中进行了一些调试。
除了将所有值0..255通过缩放255.0f转换为浮点数0.0..1.0之外,计算几乎都是简单的。这会在(IEEE754浮点数表示的)最低有效位中引入舍入误差。
此处C = 254转换为〜R = 1(请注意,两个数组都是同一对象,并且已就地更新,因此在转换中会丢失CMYK值。
在转换回整数值进行显示时,通过适当的上舍入舍入,这应该没有任何问题。但是,深入研究ColorModel
本身,发现例程将浮点数组转换为压缩的32位RGB值的例程使用了此函数:
private static int to8bit(float value) {
return (int) (255.0f * value);
}
它被截断了!我不知道这是否是错误,但这当然是可用性问题。
答案 2 :(得分:1)
我也在Eclipse上的Windows上使用Java 8,它给了我相同的结果,但这不是问题。它对您来说很好用,但是将RGB转换为CMYK的方式与将CMYK转换为RGB的方式不同。 您可以在线查看此转换器中的内容:
https://www.rapidtables.com/convert/color/rgb-to-cmyk.html
CMYK适用于青色,品红色和黄色百分比。另一方面,红色,绿色和蓝色的RGB值在0到255之间。 在我通过的网络中,您放置了该转换的公式,并且无法以相同的双向方式工作。