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

DataGridに画像リストを表示した時の問題

分類:[.NET]

 ご無沙汰です、
こちらのHPにあるTips[DataGridのセルに画像を表示する]を参考に画像リストを表示出来るようにしましたが、最初にリストを表示する時はそれなりにずらずらっと表示してくれます。
 問題は「スクロールをすると再描画がとても遅くなってしまう」ということです。
コードはただ表示するだけになっていますので、
これはただサムネールしていないからかなと、思いTips[DataGridのセルに画像を表示する]のClass DataGridImageTextBoxColumn の画像を読み込む部分を下記のようにサムネール表示に変更しましたが、どうも関係ないみたいです、エキスプローラの縮小版の表示みたいにスクロールしても高速に画像の描画を行なう事は可能でしょうか? 

Dim fs As System.IO.FileStream
fs = New System.IO.FileStream(fileName,IO.FileMode.Open,IO.FileAccess.Read)
'画像を読み込む
Dim bmp As New Bitmap(fs)

’サムネール
Dim myThumbnail As Image = bmp.GetThumbnailImage100,100,Nothing,IntPtr.Zero)

'boundsの大きさで画像を表示する
'(セルの大きさに合わせて画像が表示される)
g.DrawImage(myThumbnail, bounds)
fs.Close()

マイクロソフトサーチで画像 描画 高速 .net で検索しても有用な情報が得られませんでした。


又スクロールをする度に、ものすごいメモリリークを起こしています
がこれはDataGridの仕様なんでしょうか?

ちなみに、DataGrid メモリリーク等で調べましたが有用な情報は得られませんでした。

最後に
前に「スキャニングした画像データを等倍で画面に表示して印刷時も等倍で印刷したい」
を質問しましたがまだ奮闘中ですので気長に報告をお待ちください。
> こちらのHPにあるTips[DataGridのセルに画像を表示する]を参考に画像リストを表示出来るようにしましたが、最初にリストを表示する時はそれなりにずらずらっと表示してくれます。
>  問題は「スクロールをすると再描画がとても遅くなってしまう」ということです。

DataGridのセルに画像を表示する
http://dobon.net/vb/dotnet/datagrid/drawimage.html

遅くなる一番の原因はPaintが呼び出されるたびに画像を読み込んでいるということでしょう。(サンプルコードはあくまで画像を表示する方法を説明しているだけですので、この点はあえて無視しています。)これを解決するには、配列やコレクションに読み込んだ画像(Bitmapオブジェクト)を保存しておくというような方法が考えられます。例えば次のようになります。ここではHashtableを使っています。上記Tipsのサンプル同様、これだけでは不完全で、実際に使うには考慮すべき点が多々あると思ってください。

----------
Public Class DataGridImageTextBoxColumn
Inherits DataGridTextBoxColumn

Private _images As New Hashtable '<--変更

'Paintメソッドをオーバーライドする
Protected Overloads Overrides Sub Paint( _
ByVal g As Graphics, _
ByVal bounds As Rectangle, _
ByVal source As CurrencyManager, _
ByVal rowNum As Integer, _
ByVal backBrush As Brush, _
ByVal foreBrush As Brush, _
ByVal alignToRight As Boolean _
)
'セルの値を取得する
Dim cellValue As Object = _
Me.GetColumnValueAtRow(source, rowNum)
If (Not cellValue Is Nothing) Then
'表示するファイル名の取得
Dim fileName As String
fileName = CType(cellValue, String)
Try
If Not _images.Contains(fileName) Then
'以下6行変更
Try
'画像を読み込む
_images.Add(fileName, New Bitmap(fileName))
Catch
_images.Add(fileName, Nothing)
End Try
End If
'boundsの大きさで画像を表示する
'(セルの大きさに合わせて画像が表示される)
g.DrawImage(_images(fileName), bounds)
(以下省略)
----------
ありがとうございます、問題解決でございます。

> 遅くなる一番の原因はPaintが呼び出されるたびに画像を読み込んでいるということでしょう。
なるほどそういうことでしたか、ブレークポイントをDataGridImageTextBoxColumnに設定して
デバックをしていれば分かっていたかもしれませんが、多分どうすれば良いかまで分からなかったと思います。


メモリリークも途中まで上がってから元に戻りましたのでほぼ問題無いと思います。
あと画像を読み込む部分をサムネイルに変更しました。

> ----------
> If (Not cellValue Is Nothing) Then
> '表示するファイル名の取得
> Dim fileName As String
> fileName = CType(cellValue, String)
> Try
> If Not _images.Contains(fileName) Then
> '以下6行変更
> Try
> '画像を読み込む アフロ変更↓
_images.Add(fileName, New Bitmap(fileName).GetThumbnailImage(100, 100, Nothing, IntPtr.Zero))
> Catch
> _images.Add(fileName, Nothing)
> End Try
> End If
> 'boundsの大きさで画像を表示する
> '(セルの大きさに合わせて画像が表示される)
> g.DrawImage(_images(fileName), bounds)
> (以下省略)
> ----------
上のコード、もしかするとインデントされてないかも
あ 解決済みチェック忘れてしまった。
解決済み!

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