[C#] 画像ファイルを高速に読み込むには

ちょっと古い記事(2007/05/24)だけど反応。

画像ファイルを高速に読み込むには?[2.0のみ、C#、VB] - @IT
http://www.atmarkit.co.jp/fdotnet/dotnettips/597fastloadimg/fastloadimg.html

この記事では画像ファイルからImageオブジェクトを作成する手順を解説している。気になったのは、Imageクラスのインスタンスを作成する際に「画像データの検証」をするかしないかのオプションがあり、それによって処理速度が大きく左右されるということ。

自分で検証してみる。そのために、フォームにPictureBoxを配置し、画像ファイルを読み込んで生成したImageオブジェクトをPictureBoxにアサインする、という簡単なテストプログラムを作成した。画像ファイルからどのようにImageオブジェクトを生成するか、3つの方法を試してみたい。

方法1: Image.FromFile()を使う

もっとも簡単な方法。

方法2: Image.FromStream()を使う

ファイル名だけ指定してFromStream()を使う。

方法3: Image.FromStream()を使う – イメージデータ検証無し

2つのオプション付きのFromStream()を試してみる。2番目の引数はカラーマネージメント情報の適用の有無、3番目の引数はイメージデータの検証の有無を指定する。共に false と指定。

処理速度

前回のエントリ同様に、4896×3264ピクセルのサンプル画像を使って処理時間を計測した。結果は方法3が他の2つより2桁も速い。「イメージデータの検証」を無しにすると読み込み速度を向上できることがわかった。

# 使用関数 処理時間
方法1 Image.FromFile() 132ms
方法2 Image.FromStream() 155ms
方法3 Image.FromStream() イメージデータ検証なし 2ms

環境: Windows 7 Ultimate SP1 (64bit), Intel Core i7 3.4GHz, RAM 16GB, Visual Studio 2012

イメージデータの検証は何をしているのか?

イメージデータの検証は何をしているのかという疑問が残った。Image.FromStreamメソッドはMSDNでは以下の通り説明されている。

Image.FromStream メソッド (Stream, Boolean, Boolean) オプションで埋め込み色管理情報の使用とイメージ データの検証を行い、指定したデータ ストリームから Image を作成します。 public static Image FromStream( Stream stream, bool useEmbeddedColorManagement, bool validateImageData ) useEmbeddedColorManagement データ ストリームに埋め込まれている色管理情報を使用する場合は true。それ以外の場合は false。 validateImageData イメージ データを検証する場合は true。それ以外の場合は false。 useEmbeddedColorManagement パラメーターは、データ ストリームに埋め込まれた色管理情報に従って、新しい Image に色補正を適用させるかどうかを指定します。 埋め込み情報には、ICC (International Color Consortium) プロファイル、ガンマ値、および色度情報を含めることができます。

useEmbeddedColorManagementの意味はなんとなくわかる。だけどvalidateImageDataの意味がわからない。「イメージデータを検証する」って何をしてるの?そういえば.NETってオープンソースでPC以外のプラットフォームにも移植されてたよな、と思って調べたらソースらしきものが見つかった。

Image.cs source code in C# .NET
http://www.dotnetframework.org/default.aspx/DotNET/DotNET/8@0/untmp/whidbey/ REDBITS/ndp/fx/src/CommonUI/System/Drawing/Image@cs/1/Image@cs

このソースを見ると、validateImageDataがtrue、すなわち「イメージ データを検証する」とした場合、GDI+のGdipImageForceValidationが呼ばれている。だけど、ネットでGdipImageForceValidationの情報を探すも見つからず。かろうじてMSDNの以下ページに「This function forces validation of the image.」とだけ記載されていた。

Image Functions (Windows)
http://msdn.microsoft.com/en-us/library/ms534041(v=vs.85).aspx

更に情報を求めてネットを検索していたら、Windowsアプリを別プラットフォームで動かすWINEというプロジェクトを見つけた。

WineHQ – Run Windows applications on Linux, BSD, Solaris and Mac OS X
http://www.winehq.org/

GDI+の互換ライブラリが含まれているらしいのでダウンロードしてソースを閲覧したのだが、関数は存在したけど処理は実装されてなかった。Image.FromStreamメソッドの「イメージデータの検証」は何をやっているのか、残念ながらわからずじまい。