您现在可以使用 ImageIO 读取 .HDR。:-)
这是第一个版本,所以边缘可能有点粗糙,但应该适用于标准(默认设置)Radiance RGBE.HDR
文件。
返回的图像将是BufferedImage
带有DataBufferFloat
背景的自定义图像(即,样本将采用 3 个样本,32 位float
交错 RGB 格式)。
默认情况下,应用一个简单的全局色调映射,所有 RGB 值都将被归一化到范围 [0...1](这允许任何人都可以使用ImageIO.read(hdrFile)
,并且图像会在非常合理的时间内看起来有些合理)。
也可以使用 a 将 a 传递HDRImageReadParam
给ImageReader
实例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(...));