JColorChooser 中的异常行为(或可能的错误)
Anomalous behavior (or possible bug) in JColorChooser
使用 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);
}
}
- 在两个面板中,select CMYK 并输入任何有效的 CMYK 数字。两个面板必须具有相同的值。
- 现在比较每个面板的 RGB 值。他们应该是一样的。
- Select 单个面板并将滑块重置为 0。
- 现在在同一个面板中重新输入 RGB 值。
- 将两个面板切换为 CMYK。我看到的面板中的值不同。
请注意,当采用另一种方式时(即先 selecting RGB 并重新输入 CMYK 值),一切都如预期的那样工作。我错过了什么吗
转换过程需要什么,或者这是一个错误?
我是 运行 Java 10 Windows 10 我的 IDE 是 Eclipse。
也发布在 http://www.javaprogrammingforums.com/java-theory-questions/41836-possible-bug-jcolorchooser.html
我也在 Eclipse 上使用 Java 8 和 Windows,它给了我相同的结果,但这不是问题所在。它对您来说工作正常,但将 RGB 转换为 CMYK 的方式与将 CMYK 转换为 RGB 的方式不同。
你可以在这个在线转换器中看到它:
https://www.rapidtables.com/convert/color/rgb-to-cmyk.html
CMYK 适用于青色、品红色和黄色百分比。另一方面,RGB 具有从 0 到 255 的红色、绿色和蓝色值。
在我传递给您的网络中,您输入了该转换的公式,并且无法以相同的双向方式工作。
从一种(离散)颜色模型到另一种(离散)颜色模型的转换永远不可能完美。
CMYK 到 RGB 到 CMYK 在 JColorChooser 中永远无法完美工作的原因很简单,因为 JColorChooser 显示 整数 而不是浮点数。例如在 CMYK 模型中选择 yellow=255 并返回到 RGB。您会看到这种黄色是由 red=255 和 green=255 混合而成的。现在回到 CMYK,将黄色降低为 254 并检查 RGB 值 - 它仍然是 red=255 和 green=255!
现在将 CMYK 中的黄色更改为 253,然后返回到 RGB。红色和绿色仍然是 255,蓝色加上值 1。CMYK 黄色 = 254(之前的情况)的正确值可能是蓝色 = 0.4,但为了使使用更简单,JColorChooser 中只显示整数,因此蓝色显示为0.
由于这些整数颜色模型的 'color sensitivity' 不同,这个数字问题变得更加严重。虽然 CMYK 有 4 个维度(青色、品红色、黄色、基调),因此可以表示 256^4 = 4294967296 种不同的颜色,但 RGB 有 3 个维度,只能表示 256^3 = 16777216 种颜色。因此,在将 CMYK 转换为这种类型的 RGB 时,您总是会丢失很多信息。
换句话说,平均而言,CMYK 颜色 space 中的 256 个点仅由 RGB 颜色 space 中的 1 个点表示。当您将一种颜色从 RGB 转换回 CMYK 时,平均而言,CMYK space 中的 255 种颜色永远不会是 'reached'.
我在 JColorChooser
使用的颜色模型中进行了一些调试,特别是 ColorModelCMYK
(包私有 class)。
除了所有值 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);
}
它被截断了!我不知道这是否是一个错误,但这肯定是一个可用性问题。
使用 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);
}
}
- 在两个面板中,select CMYK 并输入任何有效的 CMYK 数字。两个面板必须具有相同的值。
- 现在比较每个面板的 RGB 值。他们应该是一样的。
- Select 单个面板并将滑块重置为 0。
- 现在在同一个面板中重新输入 RGB 值。
- 将两个面板切换为 CMYK。我看到的面板中的值不同。
请注意,当采用另一种方式时(即先 selecting RGB 并重新输入 CMYK 值),一切都如预期的那样工作。我错过了什么吗 转换过程需要什么,或者这是一个错误?
我是 运行 Java 10 Windows 10 我的 IDE 是 Eclipse。
也发布在 http://www.javaprogrammingforums.com/java-theory-questions/41836-possible-bug-jcolorchooser.html
我也在 Eclipse 上使用 Java 8 和 Windows,它给了我相同的结果,但这不是问题所在。它对您来说工作正常,但将 RGB 转换为 CMYK 的方式与将 CMYK 转换为 RGB 的方式不同。 你可以在这个在线转换器中看到它:
https://www.rapidtables.com/convert/color/rgb-to-cmyk.html
CMYK 适用于青色、品红色和黄色百分比。另一方面,RGB 具有从 0 到 255 的红色、绿色和蓝色值。 在我传递给您的网络中,您输入了该转换的公式,并且无法以相同的双向方式工作。
从一种(离散)颜色模型到另一种(离散)颜色模型的转换永远不可能完美。
CMYK 到 RGB 到 CMYK 在 JColorChooser 中永远无法完美工作的原因很简单,因为 JColorChooser 显示 整数 而不是浮点数。例如在 CMYK 模型中选择 yellow=255 并返回到 RGB。您会看到这种黄色是由 red=255 和 green=255 混合而成的。现在回到 CMYK,将黄色降低为 254 并检查 RGB 值 - 它仍然是 red=255 和 green=255!
现在将 CMYK 中的黄色更改为 253,然后返回到 RGB。红色和绿色仍然是 255,蓝色加上值 1。CMYK 黄色 = 254(之前的情况)的正确值可能是蓝色 = 0.4,但为了使使用更简单,JColorChooser 中只显示整数,因此蓝色显示为0.
由于这些整数颜色模型的 'color sensitivity' 不同,这个数字问题变得更加严重。虽然 CMYK 有 4 个维度(青色、品红色、黄色、基调),因此可以表示 256^4 = 4294967296 种不同的颜色,但 RGB 有 3 个维度,只能表示 256^3 = 16777216 种颜色。因此,在将 CMYK 转换为这种类型的 RGB 时,您总是会丢失很多信息。
换句话说,平均而言,CMYK 颜色 space 中的 256 个点仅由 RGB 颜色 space 中的 1 个点表示。当您将一种颜色从 RGB 转换回 CMYK 时,平均而言,CMYK space 中的 255 种颜色永远不会是 'reached'.
我在 JColorChooser
使用的颜色模型中进行了一些调试,特别是 ColorModelCMYK
(包私有 class)。
除了所有值 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);
}
它被截断了!我不知道这是否是一个错误,但这肯定是一个可用性问题。