Image & ImageView in JavaFX

突然ですが...
実は 前回の『Drag and Drop on JavaFX Part 6 (FileDroppable)』のサンプルを こっそり修正しちゃいました。
きっと誰も気づいてないだろうなぁ...

ちょっと初歩的なミスなので、 あまり大きな声では言えませんが...
また同じ過ちをおかさないように メモしておくことにしました。
多分いないとは思うのですが、 私と同じ過ちをおかそうとしている人の 助けになるかもしれないし...

で前置きはこれくらいにして...
私のおかした過ちですが、 それは Image と ImageView の使い方です。
それも一番重要なサイズの指定方法...

前回のサンプルではファイル等からドラッグ したイメージを Image と ImageView でタイルの 枠に収まるようにサイズを調整して表示していました。
イメージのサイズ変更は 何も考えず...

ImageView {
    fitWidth:  150
    fitHeight: 150
    image: Image { url: "...." }
}
のような感じで ImageView の fitWidth と fitHeight で行なっていました。
実はこれが大きな過ちだったのです。

と言うのも...
ImageView は 画像をどのように表示するかを表すクラスで 画像そのものを表すクラスではありません。
つまり、fitWidth や fitHeight は画像自体のサイズを変える訳ではなく、 画像の表示サイズを変えるだけです。
最近のデジカメは 一般的なものでも 撮影した写真のサイズは 数MBにもなります。
それをそのまま JavaFX で読み込んでしまうとあっという間にヒープメモリを使い果たしてしまいます。

前回のサンプルのように サムネイルを表示する場合は

ImageView {
    image: Image {
        width:  150
        height: 150
        url: "...."
    }
}
のように Image の width と height を指定して 画像自体のサイズを 変更して読み込むべきです。

たったこれだけの記述の違いでどれほどの効果があるか実際に下のサンプルで確認してみてください。
その違いに驚くかもしれません。

今回のサンプルでは 上記の 2パターンで画像を表示した際のヒープメモリを確認することができます。
現在使用しているヒープメモリのサイズはウィンドウの右下に表示されます。
どちらも同じ大きさで表示していますが...

  1. パターンA は ImageView で画像の表示サイズを変更
  2. パターンB は Image で画像自体のサイズを変更
のように実装は異なります。

追伸:

どうやら、このサンプル Windows XP だと パターンBに切り替えた際に画像が表示されないことがあるようです。
その場合は あきらめずに 何度か パターンA <-> パターンB を切り替えると表示されるように なります。