- PR -

Image.FromFileを高速にしたいです

投稿者投稿内容
さくろん
会議室デビュー日: 2006/02/04
投稿数: 3
お住まい・勤務地: 東京都
投稿日時: 2006-02-04 04:33
はじめまして、さくろんと申します。

VB.NETで大量のJPEG画像(1MB弱のJPEGファイル3000枚程度)を一覧表示させるプログラムを作成しています。
サーバー側のあるフォルダに溜め込まれたJPEGファイルよりサムネイルを生成するため、JPEGファイルからImageインスタンスを生成したのですが、「Image.FromFile」を実行している部分がボトルネックになっていることがわかりました。
処理速度としては、400ms程度なのですが、これをもっと減らしたいと考えています。
その他画像表示処理を含めて、1枚表示するために平均600ms程かかっており、簡単に試算すると
10枚で6秒
100枚で60秒
1000枚で600秒
程度かかってしまいます。
エクスプローラーの縮小表示を行った際、結構なスピードでサムネイル画像が表示されますが、あのスピードくらいでればと考えています。

−−−ここからプログラムソース−−−

' JPEGファイルからImageインスタンスを生成
Dim jpeg_image As Image = Image.FromFile("800KB_JpegImage.jpg") <−ここが遅い!


' サムネイル用Imageインスタンス生成
Dim thumb_image As Image = jpeg_image.GetThumbnailImage(100, 100, Nothing, New IntPtr)

' Imageインスタンス破棄
jpeg_image.Dispose()

−−−ここまでプログラムソース−−−

開発環境
 CPU Pentium4 2GHz
 メモリ 1GB
 HDD 70GB

ディスクアクセスが遅いせいとも思うのですが、もっと効率のよい読み込み方式など心当たりがあるようでしたら、ご教授願えませんでしょうか?

甕星
ぬし
会議室デビュー日: 2003/03/07
投稿数: 1185
お住まい・勤務地: 湖の見える丘の上
投稿日時: 2006-02-04 09:16
既に1行のコードでしかないわけで、.NET Frameworkの機能を使う限り、高速化の余地は殆ど残されていません。対策としては、以下の何れかしかないんじゃない?

  • 複数のスレッドに処理を分散させる。
  • JPEGファイルを独自に作成する。


_________________
甕星 <mikahosi@abox9.so-net.ne.jp>
http://blogs.msmvp.jp/mikahosi/
unibon
ぬし
会議室デビュー日: 2002/08/22
投稿数: 1532
お住まい・勤務地: 美人谷        良回答(20pt)
投稿日時: 2006-02-04 10:27
引用:

さくろんさんの書き込み (2006-02-04 04:33) より:
エクスプローラーの縮小表示を行った際、結構なスピードでサムネイル画像が表示されますが、あのスピードくらいでればと考えています。


推測ですが、あれは事前に作っておいてキャッシュしているのではないでしょうか?

引用:

さくろんさんの書き込み (2006-02-04 04:33) より:
ディスクアクセスが遅いせいとも思うのですが、もっと効率のよい読み込み方式など心当たりがあるようでしたら、ご教授願えませんでしょうか?


とりあえずは、実行中にタスクマネージャーで CPU 使用率を調べてみてはどうでしょうか。
(シングル CPU の場合、) 100% に近い値になっていたらディスク待ちはありませんので、純粋に処理(JPEG 展開や縮小)が重いだけです。

#以下、後で追加。
http://www.google.co.jp/search?hl=ja&q=GetThumbnailImage+FromFile&lr=lang_ja
で検索すると、みなさん悩んでいらっしゃるような。
うがった見方ですが、昔から、使いやすい高水準の API は、サードパーティーの活躍の余地を残すために、あえて遅目になっているものです。

[ メッセージ編集済み 編集者: unibon 編集日時 2006-02-04 10:31 ]
さくろん
会議室デビュー日: 2006/02/04
投稿数: 3
お住まい・勤務地: 東京都
投稿日時: 2006-02-04 15:33
引用:

甕星さんの書き込み (2006-02-04 09:16) より:
既に1行のコードでしかないわけで、.NET Frameworkの機能を使う限り、高速化の余地は殆ど残されていません。対策としては、以下の何れかしかないんじゃない?

  • 複数のスレッドに処理を分散させる。
  • JPEGファイルを独自に作成する。



返信ありがとうございます!

対象となる画像はデジタルカメラで撮影した画像なのですが、どうやらこれにはサムネイル用の画像が入っているらしく、そいつを抽出&ファイル化したものをFromFileで読み込もうかなぁとも考えているんです。
ただ、そうなると新規開発になってしまい、猶予もないため、出来れば変更の少ない方式で対応したいと考えています。
FromStreamを使用しても、結局FromFileと同じパフォーマンスしか出ないようですので・・・。

さくろん
会議室デビュー日: 2006/02/04
投稿数: 3
お住まい・勤務地: 東京都
投稿日時: 2006-02-04 15:39
引用:

unibonさんの書き込み (2006-02-04 10:27) より:
引用:

さくろんさんの書き込み (2006-02-04 04:33) より:
エクスプローラーの縮小表示を行った際、結構なスピードでサムネイル画像が表示されますが、あのスピードくらいでればと考えています。


推測ですが、あれは事前に作っておいてキャッシュしているのではないでしょうか?

引用:

さくろんさんの書き込み (2006-02-04 04:33) より:
ディスクアクセスが遅いせいとも思うのですが、もっと効率のよい読み込み方式など心当たりがあるようでしたら、ご教授願えませんでしょうか?


とりあえずは、実行中にタスクマネージャーで CPU 使用率を調べてみてはどうでしょうか。
(シングル CPU の場合、) 100% に近い値になっていたらディスク待ちはありませんので、純粋に処理(JPEG 展開や縮小)が重いだけです。

#以下、後で追加。
http://www.google.co.jp/search?hl=ja&q=GetThumbnailImage+FromFile&lr=lang_ja
で検索すると、みなさん悩んでいらっしゃるような。
うがった見方ですが、昔から、使いやすい高水準の API は、サードパーティーの活躍の余地を残すために、あえて遅目になっているものです。

[ メッセージ編集済み 編集者: unibon 編集日時 2006-02-04 10:31 ]



返信ありがとうございます!

画像読み込み処理でWEBサーバーのメモリー・CPU・HDDはフル稼働していました。(苦笑
クライアント側では完全にサーバーからの応答待ちとなっており、明らかにサーバーの処理がボトルネックになっていることがわかります。
大きいファイルを扱う場合、やはりWEBではうまく設計をしておかないとえらいことになりますね。。。

ありがとうございました。
じゃんぬねっと
ぬし
会議室デビュー日: 2004/12/22
投稿数: 7811
お住まい・勤務地: 愛知県名古屋市
投稿日時: 2006-02-04 23:08
引用:

unibonさんの書き込み (2006-02-04 10:27) より:

推測ですが、あれは事前に作っておいてキャッシュしているのではないでしょうか?


その通りです。
Thumb.db がキャッシュにあたります。
設定次第でキャッシュは無効にできます... って、そんなことはどうでもいいですねw

引用:

さくろんさんの書き込み (2006-02-04 15:39) より:

WEBサーバーのメモリー・CPU・HDDはフル稼働していました。


む、サーバサイドの話でしたか...
工数をかけたくないとなると、諦めモードになりますね...

_________________
C# と VB.NET の入門サイト
じゃんぬねっと日誌
mei
大ベテラン
会議室デビュー日: 2003/04/08
投稿数: 114
投稿日時: 2006-02-05 03:05
こんばんは、meiです。

引用:

VB.NETで大量のJPEG画像(1MB弱のJPEGファイル3000枚程度)を一覧表示させるプログラムを作成しています。
サーバー側のあるフォルダに溜め込まれたJPEGファイルよりサムネイルを生成するため、JPEGファイルからImageインスタンスを生成したのですが、「Image.FromFile」を実行している部分がボトルネックになっていることがわかりました。


どこかでトレードオフするしか無いですね。
JPEGからサムネイルを取る方法にすると余分な工数が掛かるとのことなので、今のプログラムが作っているサムネイルを一度ファイルに保存して、それを読み込むようにするとかはどうでしょうか?
サムネイル作成プログラムは毎回動かす必要はないので、ファイル登録時に動作させるようにすれば、表示部分はサムネイルをロードするだけになります。

もっと安直な方法だと、読み込みが速いファイルフォーマットに変更してしまうとか。
ウチで簡単にテストしてみたところ、
30個のJPEGファイル(合計10MB)を読み込むのに3.5秒
PNGに変更すると2.8秒(ファイルサイズの合計は95MB)
BMPに変更すると0.6秒(ファイルサイズの合計は179MB)
となりました。

余分にディスクが食いますが、HDD増設に掛かる費用とプログラミングの工数を秤に掛けて安い方を選択するって考えもありかもしれません。
なちゃ
ぬし
会議室デビュー日: 2003/06/11
投稿数: 872
投稿日時: 2006-02-05 06:27
引用:

meiさんの書き込み (2006-02-05 03:05) より:
BMPに変更すると0.6秒(ファイルサイズの合計は179MB)


ぐほ、300MB/secのHDDとはこれいかに。

とまあ、メモリ容量やらキャッシュやらHDDの転送速度自体やら
いろんな要素が絡んでくるので、何をやるにも慎重さは必要です、念のため。

スキルアップ/キャリアアップ(JOB@IT)