VB.netでListViewに約4100枚のjpg画像ファイルを読み込んでサムネイルで表示しているのですが、ボタンを押してサムネイルが表示されるまで約6分間かかります。これをもっと早く読み込めるように改良したいのですがどうすればいいのかわかりません。画質は大幅に下がっても構いません。
使用しているパソコンのスペック
使用OS Windows10
メモリ 8GB
CPU Intel Core i5-3230M 2.60GHz
処理の実行中は実行しているプロセスのCPU使用率が35パーセントぐらいになります。
ここを参考にしました
VB
Public Class Form1 ' 幅w、高さhのImageオブジェクトを作成 Function createThumbnail(ByVal image As Image, ByVal w As Integer, ByVal h As Integer) As Image Dim canvas As New Bitmap(w, h) Dim g As Graphics = Graphics.FromImage(canvas) g.FillRectangle(New SolidBrush(Color.White), 0, 0, w, h) Dim fw As Double = CDbl(w) / CDbl(image.Width) Dim fh As Double = CDbl(h) / CDbl(image.Height) Dim scale As Double = Math.Min(fw, fh) Dim w2 As Integer = CInt(image.Width * scale) Dim h2 As Integer = CInt(image.Height * scale) g.DrawImage(image, (w - w2) \ 2, (h - h2) \ 2, w2, h2) g.Dispose() Return canvas End Function ' ButtonのClickイベントのハンドラ Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click Dim imageDir As String = "C:\Users\user\Pictures" ' 画像ディレクトリ Dim jpgFiles As String() = System.IO.Directory.GetFiles(imageDir, "*.jpg") Dim width As Integer = 100 Dim height As Integer = 80 ImageList1.ImageSize = New Size(width, height) ListView1.LargeImageList = ImageList1 Dim original As Image For i As Integer = 0 To jpgFiles.Length - 1 Try original = Bitmap.FromFile(jpgFiles(i)) Catch original = My.Resources.Resource1._error End Try Dim thumbnail As Image = createThumbnail(original, width, height) ImageList1.Images.Add(thumbnail) ListView1.Items.Add(jpgFiles(i), i) original.Dispose() thumbnail.Dispose() Next End Sub End Class
お手数をおかけしますがよろしくお願いいたします。
追記
コードの修正によって少し早くなったのでそれを追記します。
以下のコードでほぼ2分、メモリ使用量は250メガバイトほどに短縮できました。
VB
Public Class Form1 ' 幅w、高さhのImageオブジェクトを作成 Function createThumbnail(ByVal image As Image, ByVal w As Integer, ByVal h As Integer) As Image Dim canvas As New Bitmap(w, h) Dim g As Graphics = Graphics.FromImage(canvas) g.FillRectangle(New SolidBrush(Color.White), 0, 0, w, h) Dim fw As Double = CDbl(w) / CDbl(image.Width) Dim fh As Double = CDbl(h) / CDbl(image.Height) Dim scale As Double = Math.Min(fw, fh) Dim w2 As Integer = CInt(image.Width * scale) Dim h2 As Integer = CInt(image.Height * scale) g.DrawImage(image, (w - w2) \ 2, (h - h2) \ 2, w2, h2) g.Dispose() Return canvas End Function ' ButtonのClickイベントのハンドラ Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click Dim cnt As Integer = 0 Dim imageDir As String = "C:\Users\user\Pictures" ' 画像ディレクトリ Dim jpgFiles As String() = System.IO.Directory.GetFiles(imageDir, "*.jpg") Dim width As Integer = 100 Dim height As Integer = 80 ImageList1.ImageSize = New Size(width, height) ListView1.LargeImageList = ImageList1 Dim thumbnail(jpgFiles.Length - 1) As Image Dim original As Image For i As Integer = 0 To jpgFiles.Length - 1 '①のブレイクポイントを置く Try original = Bitmap.FromFile(jpgFiles(i)) Catch original = My.Resources.Resource1._error End Try thumbnail(i) = createThumbnail(original, width, height) original.Dispose() Next ImageList1.Images.AddRange(thumbnail) '②のブレイクポイントを置く For i As Integer = 0 To jpgFiles.Length - 1 ListView1.Items.Add(jpgFiles(i), i) Next End Sub End Class
上記のコードでブレイクポイントを
①For i As Integer = 0 To jpgFiles.Length - 1
の部分と
②ImageList1.Images.AddRange(thumbnail)
の部分に置いてみて時間を計測したところ、Button1を押してから①の部分までで約1秒かかりました。
次に①から②の所までは1分38秒かかりました。次に②から最後まで走らせたら22秒かかりました。
全体で約2分かかってますが、①から②までのサムネイルを作成する処理に時間がかかっているようです。
作ったサムネイルをImageList1に追加するのとListView1.Items.Addの部分で22秒なので、サムネイルを作成する部分をもっと改善出来れば早くなると思います。
それと作っている物ですが
「Visual Studio 2017」でプロジェクトの作成は「Visual Basic」の「Windowsフォームアプリケーション(.Net Framework)」を選択してプロジェクトを作成しています。どのような目的の物を作るかというと、jpg画像ファイルビューワーです。まずディレクトリを選択してそこにある画像ファイルの一覧をサムネイルで表示して、サムネイルのどれかをダブルクリックすると別ウィンドウでその画像が拡大表示されるといったものです。
まだ回答がついていません
会員登録して回答してみよう