Exifの読み込みを早くする

この↓ページが役に立った。

写真のExif情報を読み取りたい場合、ImageオブジェクトのPropertyItemsプロパティを使うために

Bitmap bmp = new Bitmap(filePath);

のように、ファイルのパスを渡してBitmapオブジェクトを作るのが普通だ(手軽だし)。でも、たくさんの画像を一気に処理すると結構時間がかかる。自分がNASに置いていた写真のExif情報読み取り(といっても、撮影年月日だけだが)では、1000件あたり1分10秒くらいかかっていた。

…が、先のページの方法にしたら半分以下の30秒弱で処理できた。そのやりかたはこう。

FileStream fs = File.OpenRead(filePath);
Image img = Image.FromStream(fs, false, false);

FileStreamを開いて、ImageクラスのFormStreamメソッドでImageクラスのインスタンスを作る。あとはBitmapクラスと同じようにPropertyItemsから必要な情報を取ればいい。

Image.FromStreamの引数は

  1. 画像データを格納しているストリーム
  2. 色管理情報を使用するか(true : する false: しない)
  3. データの検証を行うかどうか(true : する false: しない)

で、特に3.の「データの検証」が重要。これをtrueにすると、かえって遅くなった(1000件あたり1分30秒弱)。メモリ使用量も増えていたので、ファイルを全部メモリに読み込んでいたのだろうと思う。最初に挙げたやり方でBitmapオブジェクトを作っていたときと同じくらいの消費量だったが、「検証」しているので更に遅くなったのかな。MBサイズのファイルをメモリに読み込むのに時間がかかっているようだ。

処理時間が半分以下になったのはすごく嬉しかった。ただ、

なお、画像データの検証をスキップすることによる影響については、リファレンス・マニュアルに見当たらなかったため不明である。
画像ファイルを高速に読み込むには?[2.0のみ、C#、VB] - @IT

が、少し気にはなるけど…。