0

.hdr ファイルを開いて作業する必要がありますが、imageIO はその形式をサポートしていません。

問題は、情報の損失を最小限に抑える必要があることです。32bpc は完璧で、16 は問題なく、16 未満では機能しません。

私が思いついた3つの可能な解決策があります:

  1. .HDR ファイルを開くことができるプラグインを見つけます。私はそれをたくさん探していましたが、運がありませんでした。
  2. .HDR ファイルを、プラグインを見つけられる形式に変換する方法を見つけてください。もしかしてティフ?これも試してみましたが、まだ運がありません。
  3. ダイナミック レンジを 32bpc から 16bpc に減らしてから、png に変換します。pngファイルを取得したら勝つので、これは注意が必要ですが、画像を殺さずに範囲を切り取るのは簡単ではありません..

何をするように勧めますか?これらの 3 つのオプションのいずれかを機能させる方法を知っていますか? それとももっといい考えがありますか?

4

1 に答える 1

1

ImageIO を使用して .HDR を読み取ることができるようになりました。:-)

これは最初のバージョンなので、端が少し荒いかもしれませんが、標準 (デフォルト設定) の 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(...));
于 2015-07-28T20:47:56.040 に答える