0

我需要打开一个 .hdr 文件并对其进行处理,但 imageIO 不支持该格式。

问题是我需要尽可能少地丢失信息:32bpc 是完美的,16 很好,少了 16 就不行了。

我想出了3种可能的解决方案:

  1. 找到一个允许我打开 .HDR 文件的插件。我一直在寻找它,但没有运气;
  2. 找到一种将 .HDR 文件转换为我可以找到插件的格式的方法。蒂夫也许?也试过了,但还是没有运气;
  3. 将动态范围从 32bpc 降低到 16bpc,然后将其转换为 png。这很棘手,因为一旦我有一个 png 文件,我就赢了,但是要在不杀死图像的情况下削减范围并不是那么容易..

你会推荐我做什么?您知道使这三个选项中的一个起作用的方法吗?还是你有更好的主意?

4

1 回答 1

1

您现在可以使用 ImageIO 读取 .HDR。:-)

这是第一个版本,所以边缘可能有点粗糙,但应该适用于标准(默认设置)Radiance RGBE.HDR文件。

返回的图像将是BufferedImage带有DataBufferFloat背景的自定义图像(即,样本将采用 3 个样本,32 位float交错 RGB 格式)。

默认情况下,应用一个简单的全局色调映射,所有 RGB 值都将被归一化到范围 [0...1](这允许任何人都可以使用ImageIO.read(hdrFile),并且图像会在非常合理的时间内看起来有些合理)。

也可以使用 a 将 a 传递HDRImageReadParamImageReader实例NullToneMapper。这甚至更快,但是这些float值将是非标准化的,并且可能会超过最大值。这允许您在转换为更可显示的内容之前对图像数据进行自定义、更复杂的色调映射。

就像是:

// Create input stream
ImageInputStream input = ImageIO.createImageInputStream(hdrFile);

try {
    // Get the reader
    Iterator<ImageReader> readers = ImageIO.getImageReaders(input);

    if (!readers.hasNext()) {
        throw new IllegalArgumentException("No reader for: " + hdrFile);
    }

    ImageReader reader = readers.next();

    try {
        reader.setInput(input);

        // Disable default tone mapping
        HDRImageReadParam param = (HDRImageReadParam) reader.getDefaultReadParam();
        param.setToneMapper(new NullToneMapper());

        // Read the image, using settings from param
        BufferedImage image = reader.read(0, param);
    }
    finally {
        // Dispose reader in finally block to avoid memory leaks
        reader.dispose();
    }
}
finally {
    // Close stream in finally block to avoid resource leaks
    input.close();
}

// Get float data
float[] rgb = ((DataBufferFloat) image.getRaster().getDataBuffer()).getData();

// TODO: Custom tone mapping on float RGB data

// Convert the image to something easily displayable
BufferedImage converted = new ColorConvertOp(null).filter(image, new BufferedImage(image.getWidth(), image.getHeight(), BufferedImage.TYPE_INT_RGB));

// Optionally write as JPEG or other format
ImageIO.write(converted, "JPEG", new File(...));
于 2015-07-28T20:47:56.040 回答