Image.FromFile() выдает Out of memory exception

Язык Visual Basic на платформе .NET.

Модераторы: Ramzes, Sebas

karagota
Начинающий
Начинающий
 
Сообщения: 6
Зарегистрирован: 21.11.2009 (Сб) 14:56

Image.FromFile() выдает Out of memory exception

Сообщение karagota » 26.11.2009 (Чт) 12:37

В продолжение темы viewtopic.php?f=2&t=41061

Процедура реагирует на изменение имени файла JPG в отслеживаемой с помощью FileSystemWatcher папке и добавляет в ImageList уменьшенную копию файла.

После второго события возникает Out Of memory Exception. Как с этим бороться?

Код: Выделить всё
Private Sub myWatcher_Renamed(ByVal sender As Object, ByVal e As System.IO.RenamedEventArgs) Handles myWatcher.Renamed
        Dim myImage As Image = Image.FromFile(e.FullPath)
        Dim thumb As Bitmap = getThumb(myImage)
        ImageList1.Images.Add(thumb)
        thumb.Dispose()
        thumb = Nothing
        ListView1.Items.Add(New ListViewItem(CStr(ImageList1.Images.Count - 1), ImageList1.Images.Count - 1))
        myImage.Dispose()
        myImage = Nothing
End Sub

FireFenix
Продвинутый гуру
Продвинутый гуру
Аватара пользователя
 
Сообщения: 1640
Зарегистрирован: 25.05.2007 (Пт) 10:24
Откуда: Mugen no Sora

Re: Image.FromFile() выдает Out of memory exception

Сообщение FireFenix » 26.11.2009 (Чт) 13:42

На какой строке вылетает?
что за функция getThumb?
Птицей Гермеса меня называют, свои крылья пожирая... сам себя я укрощаю
私はヘルメスの鳥 私は自らの羽根を喰らい 飼い慣らされる

karagota
Начинающий
Начинающий
 
Сообщения: 6
Зарегистрирован: 21.11.2009 (Сб) 14:56

Re: Image.FromFile() выдает Out of memory exception

Сообщение karagota » 26.11.2009 (Чт) 14:26

Исключение происходит во время вызова функции Image.FromFile().
Код функции getThumb

Код: Выделить всё
    Private Function getThumb(ByVal Im As Bitmap) As Bitmap

            Dim tw, th, tx, ty As Integer
            Dim w As Integer = Im.Width
            Dim h As Integer = Im.Height
            Dim whRatio As Single = CType(w, Single) / CType(h, Single)
            If whRatio > 1 Then
                tw = Me.ImageList1.ImageSize.Width
                th = CType(CType(tw, Single) / whRatio, Integer)

            Else
                th = Me.ImageList1.ImageSize.Height
                tw = CType(CType(th, Single) * whRatio, Integer)

            End If


            tx = (Me.ImageList1.ImageSize.Width - tw) / 2

            ty = (Me.ImageList1.ImageSize.Height - th) / 2

            Dim thumb As Bitmap = New Bitmap(Me.ImageList1.ImageSize.Width, Me.ImageList1.ImageSize.Height)

            Using g As Graphics = Graphics.FromImage(thumb)

            g.Clear(Color.White)

            g.InterpolationMode = Drawing2D.InterpolationMode.HighQualityBicubic

            g.DrawImage(Im, New Rectangle(tx, ty, tw, th), New Rectangle(0, 0, w, h), GraphicsUnit.Pixel)
       
            End Using
            Return thumb

        End Function

Nord777
Гуру
Гуру
Аватара пользователя
 
Сообщения: 1144
Зарегистрирован: 22.02.2004 (Вс) 13:15
Откуда: Подольск

Re: Image.FromFile() выдает Out of memory exception

Сообщение Nord777 » 26.11.2009 (Чт) 15:27

Скинь проект, посмотрим.
На как(ом|их) файл(е|ах) происходит исключение? На одном и том же? На разных? Размер файлов? Сколько оперативки? Что показывает в момент исключения диспетчер задач?
Microsoft Visual Studio 2008
Microsoft .NET Framework 3.5

karagota
Начинающий
Начинающий
 
Сообщения: 6
Зарегистрирован: 21.11.2009 (Сб) 14:56

Re: Image.FromFile() выдает Out of memory exception

Сообщение karagota » 26.11.2009 (Чт) 17:14

http://files.mail.ru/WL2NLZ

В папке test folder лежат две тестовые папки, которые нужно поместить на C. В папке JPG лежит один тестовый файл. Его можно размножить, назвав именами вида DSC_xxxx.jpg. Для имитации съемки запускаем программу, выбираем файл .xls, выбираем любого студента и нажимаем "начать съемку". После чего в папке JPG пакетно переименовывам все файлы, к примеру DSC_yyyy.JPG, где yyyy>xxxx - четырехзначные числа.

Исключение происходит на разных файлах. Все файлы - типа JPG, весят около 6 Мб, размер 2000*3000 пикселей.

Оперативная память 1 Гб.

Во время исключения происходят странные скачки памяти в сторону уменьшения (такое чувство, что начинает срабатывать garbage collector).
Вложения
scr.JPG
На скриншоте красным овалом окружено время работы моей программы. Первый скачок соответствует первому исключению.
scr.JPG (121.64 Кб) Просмотров: 2194

Nord777
Гуру
Гуру
Аватара пользователя
 
Сообщения: 1144
Зарегистрирован: 22.02.2004 (Вс) 13:15
Откуда: Подольск

Re: Image.FromFile() выдает Out of memory exception

Сообщение Nord777 » 26.11.2009 (Чт) 21:33

Сделай замену:

Код: Выделить всё
   Private Sub myWatcher_Renamed(ByVal sender As Object, ByVal e As System.IO.RenamedEventArgs) Handles myWatcher.Renamed
      Form1.last_exposure_cadr = e.Name().Substring(Len(e.Name()) - 8, 4)
      Me.lblLastCadr.Text = e.Name().Substring(Len(e.Name()) - 8, 4)

      myImage = Image.FromFile(e.FullPath)
      Using thumb As Bitmap = getThumb(myImage)
         ImageList1.Images.Add(thumb)
      End Using
      fileslist.Add(e.FullPath)
      ListView1.Items.Add(New ListViewItem(CStr(ImageList1.Images.Count - 1), ImageList1.Images.Count - 1))

      myImage.Dispose() '<---!
   End Sub


Код: Выделить всё
   Private Sub ListView1_SelectedIndexChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles ListView1.SelectedIndexChanged
      If Me.ListView1.SelectedIndices.Count = 0 Then Exit Sub
      Dim index As Integer = Me.ListView1.SelectedIndices(0)

      Dim Im As Image = Image.FromFile(fileslist(index))
      Dim W%, H%, X%, Y%, ImageAspect!
      W = PictureBox1.ClientRectangle.Width
      H = PictureBox1.ClientRectangle.Height
      ImageAspect = Im.Width / Im.Height

      Dim NewSize As Size
      If Im.Width < W AndAlso Im.Height < H Then
         NewSize = Im.Size
      ElseIf (W / ImageAspect) < H Then
         NewSize = New Size(W, W / ImageAspect)
      Else
         NewSize = New Size(H * ImageAspect, H)
      End If

      If NewSize.Width < W Then X = (W - NewSize.Width) / 2
      If NewSize.Height < H Then Y = (H - NewSize.Height) / 2

      Dim myImage = New Bitmap(W, H)
      Using G As Graphics = Graphics.FromImage(myImage)
         G.InterpolationMode = Drawing2D.InterpolationMode.HighQualityBicubic
         G.DrawImage(Im, X, Y, NewSize.Width, NewSize.Height)
      End Using

      PictureBox1.Image = myImage
      Im.Dispose() '<---!
      GC.Collect(2, GCCollectionMode.Forced) '<---!
   End Sub
Microsoft Visual Studio 2008
Microsoft .NET Framework 3.5

karagota
Начинающий
Начинающий
 
Сообщения: 6
Зарегистрирован: 21.11.2009 (Сб) 14:56

Re: Image.FromFile() выдает Out of memory exception

Сообщение karagota » 27.11.2009 (Пт) 16:37

В тестовом режиме программа падать перестала, но вот в "боевом" пока падает (видимо потому что в это время параллельно происходит копирование фотографий с фотоаппарата и одновременная их конвертация из RAW в JPG, которые отжирают и без того скромные системные ресурсы).

Очень интересная строчка
Код: Выделить всё
GC.Collect(2, GCCollectionMode.Forced)

Nord777
Гуру
Гуру
Аватара пользователя
 
Сообщения: 1144
Зарегистрирован: 22.02.2004 (Вс) 13:15
Откуда: Подольск

Re: Image.FromFile() выдает Out of memory exception

Сообщение Nord777 » 27.11.2009 (Пт) 17:10

Очень интересная строчка

Код: Выделить всё
GC.Collect(2, GCCollectionMode.Forced)

Это принудительная сборка мусора во втором поколении.
Там лежат большие по обьему занимаемой памяти обьекты.
Более подробно можно почитать к примеру тут:
http://www.rsdn.ru/article/dotnet/GC.xml
Microsoft Visual Studio 2008
Microsoft .NET Framework 3.5


Вернуться в Visual Basic .NET

Кто сейчас на конференции

Сейчас этот форум просматривают: AhrefsBot и гости: 50

    TopList