【问题标题】:Converting grayscale image pixels to defined scale将灰度图像像素转换为定义的比例
【发布时间】:2014-11-10 21:16:23
【问题描述】:

我希望使用我在 Photoshop 中创建的非常粗略的高度图来为我定义一个平铺的等距网格:

地图: http://i.imgur.com/jKM7AgI.png

我的目标是遍历图像中的每个像素,并将该像素的颜色转换为我选择的比例,例如 0-100。

目前我正在使用以下代码:

    try
    {
        final File file = new File("D:\\clouds.png");
        final BufferedImage image = ImageIO.read(file);

        for (int x = 0; x < image.getWidth(); x++) 
        {
            for (int y = 0; y < image.getHeight(); y++) 
            {
                int clr = image.getRGB(x, y) / 99999;
                if (clr <= 0)
                    clr = -clr;

                System.out.println(clr);        
            }
        }
    }
    catch (IOException ex)
    {
         // Deal with exception
    }

这在一定程度上有效;位置 0 处的黑色像素为 167,位置 999 处的白色像素为 0。但是,当我将某些像素插入到图像中时,我得到了一些奇怪的结果,例如,非常接近白色的灰色像素返回超过 100,而我期望它是个位数。

我可以使用其他解决方案来产生更可靠的结果吗?

非常感谢。

【问题讨论】:

    标签: java heightmap


    【解决方案1】:

    getRGB 返回打包到一个int 中的所有通道,因此您不应该使用它进行算术运算。也许改用 RGB 向量的范数?

    for (int x = 0; x < image.getWidth(); ++x) {
        for (int y = 0; y < image.getHeight(); ++y) {
            final int rgb = image.getRGB(x, y);
            final int red   = ((rgb & 0xFF0000) >> 16);
            final int green = ((rgb & 0x00FF00) >>  8);
            final int blue  = ((rgb & 0x0000FF) >>  0);
            // Norm of RGB vector mapped to the unit interval.
            final double intensity =
                Math.sqrt(red * red + green * green + blue * blue)
                / Math.sqrt(3 * 255 * 255);
        }
    }
    

    请注意,还有 java.awt.Color 类可以使用 getRGB 返回的 int 进行实例化,并提供 getRedgetGreengetBlue 方法,如果您不想这样做自己动手操作。

    【讨论】:

    • 谢谢。你能用外行的方式解释上面的代码在做什么吗? (特别是按位运算的行)此外,您的代码产生的范围从 0.4 到 1,我该如何调整它来更改范围?干杯。
    • 他们提取红色、绿色和蓝色部分。请参阅我的更新提到java.awt.Color。你可能会觉得它更安全。正如另一个答案所指出的,如果您的图像始终灰度,则三个通道将始终相同,因此您只能选择其中一个。
    • 啊,我明白了,谢谢你的解释。我接受了另一个答案,因为它对我个人来说更简单,更容易理解。我不太了解向量范数部分,无法舒适地使用它。
    【解决方案2】:

    由于它是灰度图,RGB 部分都是相同的值(范围为 0 - 255),因此只需从压缩整数中取出一个,找出它是 255 的百分比:

    int clr = (int) ((image.getRGB(x, y) & 0xFF) / 255.0 * 100);
    
    System.out.println(clr);        
    

    【讨论】:

      猜你喜欢
      • 2018-11-28
      • 1970-01-01
      • 1970-01-01
      • 2010-11-20
      • 1970-01-01
      相关资源
      最近更新 更多