我需要打开.hdr文件并对其进行处理,但imageIO不支持该格式。
问题在于我需要尽可能少地保持信息丢失:32bpc是完美的,16是好的,而不是16韩元的工作。
我提出了3种可能的解决方案:
你建议我做什么?你知道如何让这3个选项之一有效吗?或者你有更好的主意吗?
答案 0 :(得分:1)
You can now read .HDR using ImageIO。 : - )
这是第一个版本,所以边缘可能有点粗糙,但应该适用于标准(默认设置)Radiance RGBE .HDR
文件。你现在必须从源代码下载和构建项目,但我希望很快就能发布。
返回的图片将是自定义的BufferedImage
,其背景为DataBufferFloat
(即,样本将采用3个样本,32位float
交错RGB格式)。
默认情况下,应用简单的全局色调映射,并将所有RGB值标准化为[0 ... 1]范围(这允许任何人只使用ImageIO.read(hdrFile)
并且图像看起来有点合理,在一个非常合理的时间)。
还可以使用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(...));