DOBON.NET DOBON.NETプログラミング掲示板過去ログ

ListView のイメージ表示

環境/言語:[XP, C#, Framework 1.1]
分類:[.NET]

2004/04/19(Mon) 15:53:40 編集(投稿者)
2004/04/19(Mon) 15:48:33 編集(投稿者)

日頃からお世話になってます。
実は、treeView からのフルパスを取得して、表題コントロールにて
大小のイメージを表示したいのですが、うまくいきません。
(簡単に言えば、エクスプローラモドキです)
 ※ツリービューで選択されたフルパスを取得し、選択フォルダの
  指定拡張子のみを取得し、イメージ表示しようと思ってます。
DirectoryInfo di = new DirectoryInfo(e.Node.FullPath);

 foreach(FileInfo file in di.GetFiles("*.jpg")) {
  System.Drawing.Image img=
           Image.FromFile (di.FullName +@"\"+file.Name );
  imageList1.Images .Add (img);
 }
 listView1.LargeImageList=imageList1;

では、表示できていません。
またこのより方ですとメモリを馬鹿食いしているようなのです。
こうじゃないの等、何かご存知の方ご教授下さい。
お願い致します。
> 表示できていません。

ListView.LargeImageListに設定したものが
一覧として表示されるわけではありません。
ListViewにアイテムを表示するには、

// 今回のケースでは、項目名 = ファイル名
ListViewItem item = listView1.Add(項目名);
// 項目のアイコンの設定
item.ImageIndex = imageList1中のインデックス;

> またこのより方ですとメモリを馬鹿食いしているようなのです。

Image.FromFile()ではイメージファイルをそのままのサイズで
読み込むだけなので、ImageListに保持しているとメモリを
消費すると思われます。
Image.GetThumbnailImage()で必要なサイズに縮小してみては
どうでしょう?

Image img = Image.FromFile(フルパス);
// 表示するアイコンのサイズを指定してGetThumbnailImage()を呼び出し
// 縮小サイズのImageを取得
Image thumbnailImg = img.GetThumbnailImage(...);
// 元サイズのImageは不要
img.Dispose();
img = null;
// 縮小サイズのImageをImageListに追加
imageList1.Images.Add(thumbnailImg);
■No3718に返信(NowhereManさんの記事)
>>表示できていません。
>
> ListView.LargeImageListに設定したものが
> 一覧として表示されるわけではありません。
>
> ListViewにアイテムを表示するには、
>
> // 今回のケースでは、項目名 = ファイル名
> ListViewItem item = listView1.Add(項目名);
> // 項目のアイコンの設定
> item.ImageIndex = imageList1中のインデックス;

 え゛っ、そうだったのですか。
 てっきり、MSDN の listView の View のサンプルで
 いけるもんだと思ってました。

>>またこのより方ですとメモリを馬鹿食いしているようなのです。
>
> Image.FromFile()ではイメージファイルをそのままのサイズで
> 読み込むだけなので、ImageListに保持しているとメモリを
> 消費すると思われます。

 いや、勉強不足です。

> Image.GetThumbnailImage()で必要なサイズに縮小してみては
> どうでしょう?
>
> Image img = Image.FromFile(フルパス);
> // 表示するアイコンのサイズを指定してGetThumbnailImage()を呼び出し
> // 縮小サイズのImageを取得
> Image thumbnailImg = img.GetThumbnailImage(...);
> // 元サイズのImageは不要
> img.Dispose();
> img = null;
> // 縮小サイズのImageをImageListに追加
> imageList1.Images.Add(thumbnailImg);
NowhereMan さん、ありがとうございます。
早速、チャレンジしてご報告いたします。
まずは、お礼まで。
2004/04/20(Tue) 12:44:24 編集(投稿者)

■No3723に返信(ゆうとっとさんの記事)
NowhereMan さん、レスお礼記述してませんでした。
すいませんまた、ありがとうございます。

ヒントのように組んでいたのですが、
縮小サイズのImageをImageListに追加するまでは、
何事も無く取得設定できたのですが、問題の
imageList1 のインデックスが取得できていません。
メソッドの indexOf がサポートしてなかったり、
方法が考えつかなかったりで手こずってます。

>ListViewにアイテムを表示するには、

>// 今回のケースでは、項目名 = ファイル名
>ListViewItem item = listView1.Add(項目名);
>// 項目のアイコンの設定
>item.ImageIndex = imageList1中のインデックス;

上記の実際のインデックスの取得設定方法を
お教え下さい。
お願い致します。
> 上記の実際のインデックスの取得設定方法を
> お教え下さい。

そうですね。ImageList.Imagesプロパティ(ImageCollectionクラス)は
何故かIndexOfメソッドが未サポートになっています。
今回のケースでは、ImageListに追加する順番とListViewに追加する
順番が同じなので、次の方法ではどうでしょう?

listView1.LargeImageList = imageList1;
int index = 0;
foreach(FileInfo file in di.GetFiles("*.jpg")) {
  // 縮小サイズのImage取り出し
  Image img = Image.FromFile(...);
  Image thumbnailImg = img.GetThumbnailImage(...);
  img.Dispose();
  img = null;
  imageList1.Images.Add(thumbnailImg);
  // ListViewの項目追加
  ListViewItem item = listView1.Add(...);
  item.ImageIndex = index;
  // インデックスを更新
  index++;
}
■No3731に返信(NowhereManさんの記事)
NowhereManさん、
ゆうとっとです。
なんと言っていいか、感謝感激です。
あっ、ありがとうございます。v(^o^)v

しかし、GetThumbnailImage で指定するサイズで表示されるのではなく、
listView の ImageSize に委ねられるようですね。
またサムネイル処理で時間も食っているようですね(ToT)
NowhereManさんに教えて頂くまで数十KB のファイルでテストして
たんですが(これだと3,4秒)、現在2,3MB でテストするとPC のスペックも
あると思いますが、7枚で15〜20秒くらい掛かってます。
若干今より高速化する方法など、NowhereManさんが用いたりする方法などで
ありますか?
何か解決策が欲しいような・・・。

しかし、NowhereManさんのおかげをもちまして
表題の問題はクリアしてますので、解決済みとしておきます。

お忙しい中、NowhereManさんにはレス頂きまして、
すごく感謝してます。
このご協力を無駄にすることなく、少しでも他の投稿者の方の
お役に立てるよう”教えるくん”になるべく励んでいきたいと思います。
しかしまた投稿した時には、是非ご協力下さい。
ありがとうございました。
解決済み!
> またサムネイル処理で時間も食っているようですね(ToT)
> NowhereManさんに教えて頂くまで数十KB のファイルでテストして
> たんですが(これだと3,4秒)、現在2,3MB でテストするとPC のスペックも
> あると思いますが、7枚で15〜20秒くらい掛かってます。
> 若干今より高速化する方法など、NowhereManさんが用いたりする方法などで
> ありますか?
> 何か解決策が欲しいような・・・。

JPEGで2,3MBということですか? だとすると、画像ファイルとしては
かなり巨大な画像ですね。今回の方法は、一旦画像ファイルを読み込んで
Imageオブジェクトを生成した後、縮小画像を生成する、という方法なので、
巨大な画像ファイルの場合は時間がかかるでしょうね。

そのような巨大サイズの画像のサムネイル表示を高速化する場合は、
.NETのクラスライブラリを使用するのではなく、画像データを
自分で処理して、縮小画像を生成する処理を高速化するしかないような
気がします。つまり、JPEGファイルをバイナリモードでOpenして
JPEGフォーマットに沿ってデータを解析し、縮小画像を生成する、など。
2004/04/21(Wed) 00:47:06 編集(投稿者)

NowhereManさん、度々のレスありがとうございます。

> JPEGで2,3MBということですか? だとすると、画像ファイルとしては
> かなり巨大な画像ですね。今回の方法は、一旦画像ファイルを読み込んで
> Imageオブジェクトを生成した後、縮小画像を生成する、という方法なので、
> 巨大な画像ファイルの場合は時間がかかるでしょうね。

> そのような巨大サイズの画像のサムネイル表示を高速化する場合は、
> .NETのクラスライブラリを使用するのではなく、画像データを
> 自分で処理して、縮小画像を生成する処理を高速化するしかないような
> 気がします。つまり、JPEGファイルをバイナリモードでOpenして
> JPEGフォーマットに沿ってデータを解析し、縮小画像を生成する、など。

ん〜、NowhereManさんのでほぼ満足はしているのですが、
デジカメから直接など考えて最大でこの位のサイズで、
余りストレス無く表示できればと思ったのです。
やはりこうなりますか…。
私の非力な力ながら勉強のつもりでがんばりたいと思います。
後日またご報告したいと思います。
お付き合い頂きありがとうございました。
解決済み!

DOBON.NET | プログラミング道 | プログラミング掲示板