ちょっと古い記事(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()を使う
もっとも簡単な方法。
Image image = Image . FromFile ( "C:\\Temp\\ff_x_e1_004.JPG" ) ;
Debug . WriteLine ( "{0} x {1}" , image . Width , image . Height ) ;
pictureBox1 . Image = image ;
方法2: Image.FromStream()を使う
ファイル名だけ指定してFromStream()を使う。
FileStream stream = File . OpenRead ( "C:\\Temp\\ff_x_e1_004.JPG" ) ;
Image image = Image . FromStream ( stream ) ;
Debug . WriteLine ( "{0} x {1}" , image . Width , image . Height ) ;
pictureBox1 . Image = image ;
方法3: Image.FromStream()を使う – イメージデータ検証無し
2つのオプション付きのFromStream()を試してみる。2番目の引数はカラーマネージメント情報の適用の有無、3番目の引数はイメージデータの検証の有無を指定する。共に false と指定。
FileStream stream = File . OpenRead ( "C:\\Temp\\ff_x_e1_004.JPG" ) ;
Image image = Image . FromStream ( stream , false , false ) ;
Debug . WriteLine ( "{0} x {1}" , image . Width , image . Height ) ;
pictureBox1 . Image = image ;
処理速度
前回のエントリ同様に、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
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
public static Image FromStream ( Stream stream , bool useEmbeddedColorManagement , bool validateImageData )
{
if ( ! validateImageData ) {
IntSecurity . UnmanagedCode . Demand ( ) ;
}
if ( stream == null ) {
throw new ArgumentException ( SR . GetString ( SR . InvalidArgument , "stream" , "null" ) ) ;
}
IntPtr image = IntPtr . Zero ;
int status ;
if ( useEmbeddedColorManagement ) {
status = SafeNativeMethods . Gdip . GdipLoadImageFromStreamICM ( new GPStream ( stream ) , out image ) ;
} else {
status = SafeNativeMethods . Gdip . GdipLoadImageFromStream ( new GPStream ( stream ) , out image ) ;
}
if ( status != SafeNativeMethods . Gdip . Ok ) {
throw SafeNativeMethods . Gdip . StatusException ( status ) ;
}
if ( validateImageData ) {
status = SafeNativeMethods . Gdip . GdipImageForceValidation ( new HandleRef ( null , image ) ) ;
if ( status != SafeNativeMethods . Gdip . Ok ) {
SafeNativeMethods . Gdip . GdipDisposeImage ( new HandleRef ( null , image ) ) ;
throw SafeNativeMethods . Gdip . StatusException ( status ) ;
}
}
Image img = CreateImageObject ( image ) ;
EnsureSave ( img , null , stream ) ;
return img ;
}
このソースを見ると、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メソッドの「イメージデータの検証」は何をやっているのか、残念ながらわからずじまい。