gpt4 book ai didi

java - 如何在 Java 中创建 X% 百分比的灰色?

转载 作者:搜寻专家 更新时间:2023-11-01 01:42:43 25 4
gpt4 key购买 nike

假设我想在 Java 中使用 25% 或 31% 的灰色?

以下代码显示

    BufferedImage image = new BufferedImage(2, 2, BufferedImage.TYPE_BYTE_GRAY);

image.setRGB(0, 0, new Color(0,0,0).getRGB());
image.setRGB(1, 0, new Color(50, 50, 50).getRGB());
image.setRGB(0, 1, new Color(100,100,100).getRGB());
image.setRGB(1, 1, new Color(255,255,255).getRGB());

Raster raster = image.getData();
double[] data = raster.getPixels(0, 0, raster.getWidth(), raster.getHeight(), (double[]) null);

System.out.println(Arrays.toString(data));

显而易见的事实,RGC 与密度(?)非线性相关

[0.0, 8.0, 32.0, 255.0]

那么,如何创建给定密度的颜色?

更新

我已经尝试过@icza 和@hlg 提出的方法,还有我发现的另一种方法:

    double[] data;
Raster raster;
BufferedImage image = new BufferedImage(1, 1, BufferedImage.TYPE_BYTE_GRAY);

float[] grays = {0, 0.25f, 0.5f, 0.75f, 1};

ColorSpace linearRGB = ColorSpace.getInstance(ColorSpace.CS_LINEAR_RGB);
ColorSpace GRAY = ColorSpace.getInstance(ColorSpace.CS_GRAY);

Color color;
int[] rgb;

for(int i=0; i<grays.length; ++i) {

System.out.println("\n\nShould be " + (grays[i]*100) + "% gray");

color = new Color(linearRGB, new float[] {grays[i], grays[i], grays[i]}, 1f);

image.setRGB(0, 0, color.getRGB());
raster = image.getData();
data = raster.getPixels(0, 0, 1, 1, (double[]) null);

System.out.println("data by CS_LINEAR_RGB (hlg method) = " + Arrays.toString(data));

color = new Color(GRAY, new float[] {grays[i]}, 1f);

image.setRGB(0, 0, color.getRGB());
raster = image.getData();
data = raster.getPixels(0, 0, 1, 1, (double[]) null);

System.out.println("data by CS_GRAY = " + Arrays.toString(data));

rgb = getRGB(Math.round(grays[i]*255));

color = new Color(rgb[0], rgb[1], rgb[2]);

image.setRGB(0, 0, color.getRGB());
raster = image.getData();
data = raster.getPixels(0, 0, 1, 1, (double[]) null);

System.out.println("data by icza method = " + Arrays.toString(data));

}

并且都给出了不同的结果!

Should be 0.0% gray
data by CS_LINEAR_RGB (hlg method) = [0.0]
data by CS_GRAY = [0.0]
data by icza method = [0.0]


Should be 25.0% gray
data by CS_LINEAR_RGB (hlg method) = [63.0]
data by CS_GRAY = [64.0]
data by icza method = [36.0]


Should be 50.0% gray
data by CS_LINEAR_RGB (hlg method) = [127.0]
data by CS_GRAY = [128.0]
data by icza method = [72.0]


Should be 75.0% gray
data by CS_LINEAR_RGB (hlg method) = [190.0]
data by CS_GRAY = [192.0]
data by icza method = [154.0]


Should be 100.0% gray
data by CS_LINEAR_RGB (hlg method) = [254.0]
data by CS_GRAY = [254.0]
data by icza method = [255.0]

现在我想知道哪个是正确的?

更新 2

抱歉,灰色/白色百分比当然应该颠倒过来。

最佳答案

将 RGB 颜色转换为灰度时,使用以下权重:

0.2989, 0.5870, 0.1140

来源:Converting RGB to grayscale/intensity

在维基百科上:http://en.wikipedia.org/wiki/Grayscale

如此正式:

gray = 0.2989*R + 0.5870*G + 0.1140*B

基本上您需要的是此函数的。您需要找到 R、G 和 B 值,它们会给出您正在寻找的结果 gray 值。由于等式中有 3 个参数,因此在大多数情况下有很多 RGB 值,这将导致您要查找的 gray 值。

试想一下:一种具有高 R 分量且 G 和 B 都不给出灰色的 RGB 颜色,可能存在另一种具有一些 G 分量而 R 和 B 都不给出相同灰色的 RGB 颜色,所以有是所需灰色的多种可能的 RGB 解决方案。

算法

这是一种可能的解决方案。它所做的是尝试将第一个 RGB 分量设置为同样大,以便乘以它的权重将返回 gray。如果它“溢出”超过 255,它就会被切断,我们将 gray 减少到组件的最大值可以“表示”的数量,我们尝试对下一个组件执行此操作,剩余的 灰色 金额。

这里我使用 0..255gray 输入范围。如果您想以百分比形式指定它,只需将其转换为 gray = 255*percent/100

private static double[] WEIGHTS = { 0.2989, 0.5870, 0.1140 };

public static int[] getRGB(int gray) {
int[] rgb = new int[3];

for (int i = 0; i < 3; i++) {
rgb[i] = (int) (gray / WEIGHTS[i]);
if (rgb[i] < 256)
return rgb; // Successfully "distributed" all of gray, return it

// Not quite there, cut it...
rgb[i] = 255;
// And distribute the remaining on the rest of the RGB components:
gray -= (int) (255 * WEIGHTS[i]);
}

return rgb;
}

要验证它,使用以下方法:

public static int toGray(int[] rgb) {
double gray = 0;
for (int i = 0; i < 3; i++)
gray += rgb[i] * WEIGHTS[i];
return (int) gray;
}

测试:

for (int gray = 0; gray <= 255; gray += 50) {
int[] rgb = getRGB(gray);
System.out.printf("Input: %3d, Output: %3d, RGB: %3d, %3d, %3d\n",
gray, toGray(rgb), rgb[0], rgb[1], rgb[2]);
}

测试输出:

Input:   0, Output:   0,   RGB:   0,   0,   0
Input: 50, Output: 49, RGB: 167, 0, 0
Input: 100, Output: 99, RGB: 255, 40, 0
Input: 150, Output: 150, RGB: 255, 126, 0
Input: 200, Output: 200, RGB: 255, 211, 0
Input: 250, Output: 250, RGB: 255, 255, 219

结果显示了我们基于算法的预期:首先“填充”R 组件,一旦达到 255,“填充”G 组件,最后使用 G 组件。

关于java - 如何在 Java 中创建 X% 百分比的灰色?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26426850/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com