OutOfMemoryException загрузка большого изображения в объект Bitmap с помощью Compact Framework

У меня проблема с утечкой памяти.

У меня есть этот код в button_click:

Private Sub Button3_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button3.Click

    Dim ms As New IO.MemoryStream
    Dim bm As New Bitmap("\Application Data\imgs\IMG22.jpg")
    bm.Save(ms, Drawing.Imaging.ImageFormat.Jpeg)
End Sub

Этот код прекрасно работает, когда я запускаю.exe на своем ноутбуке (я имею в виду под windows7/32bits с полной.net framework), но когда я запускаю приложение на устройстве с WindowsMobile 6.1, приложение выдает это исключение:

SmartDeviceProject22.exe
OutOfMemoryException

в

Microsoft.AGL.Common.MISC.HandleAr(PAL_ERROR ar)
at
System.Drawing.Image.Save(Stream stream, ImageFormat format)
at
SmartDeviceProject22.Form1.Button3_Click(Object sender, EventArgs e)
at
....

Размер изображения составляет около 200 КБ, а ширина и высота около 1500 пикселей. Детали изображения:

  • Размер: 1536x2048
  • Горизонтальное разрешение: 72dpi
  • Горизонтальное разрешение: 72dpi
  • Битовая глубина: 24
  • Блок разрешения: 2
  • Цветовое представление: sRGB -

Любая помощь будет по достоинству оценена.

Я пытаюсь код @asawyer даже удалить ВСЕ код, ссылку и т. Д., И проблема сохраняется, я думаю, это что-то о ширине / высоте изображения или с компактной структурой.

Любой другой совет?

Решение и объяснение проблемы. Ну а после некоторых испытаний реальная проблема заключалась не в утечке памяти, как @pdriegen сказал, что это проблема доступной памяти.

Я изменяю свой код на это (и проверено на мобильном устройстве):

 Dim fs As IO.FileStream = IO.File.OpenRead("\Application Data\ryder\IMG23.jpg")
 Dim arrb(fs.Length) As Byte     
 fs.Read(arrb, 0, arrb.Length)
 fs.Close()
 fs.Dispose()

И с кодом выше (по-видимому) я получаю byte() (массив) изображения для хранения в базе данных, используя dataSet.

В заключение: загрузить растровый объект в memoryStream, плохая идея. Большое спасибо всем, кто нашел время, чтобы прочитать мою проблему, и особенно тем, кто публикует свой ответ.

Решение (если вам нужно показать изображение в графическом окне):

Через несколько недель это, вероятно, лучшее (бесплатное) решение: внедрите ImageHelper, как описано здесь: ImageHelper

В этом классе / образце используется пространство имен чертежей из OpenNetCF ( http://www.opennetcf.com/)

Он отлично работает и решает проблемы с памятью, загружая большие растровые изображения в память, на самом деле мы загружаем миниатюру, поэтому размер в памяти значительно уменьшается и избегает проблемы исключений OutOfMemory.

О Крисе Таке Я просто понимаю, что автор поста об ImageHelper и соучредителе OpenNetCF находится здесь в stackru, вот его профиль: ctacke

2 ответа

Решение

Я не верю, что проблема в утечке памяти. Вместо этого проблема заключается в нехватке доступной памяти.

Несмотря на то, что размер сжатого изображения составляет 200 КБ, при загрузке его в виде растрового изображения оно будет распаковано и сохранено в памяти в собственном растровом формате. Учитывая высоту и ширину 1500px каждый и допуская формат растрового изображения 32bpp (по умолчанию, если не указан), вы смотрите на 9 МБ выделенной памяти

1500 * 1500 * 4 = 9 МБ.

Учитывая ограничения памяти, присутствующие в ОС мобильного устройства (32 МБ / процесс - пространство, выделенное системными библиотеками), вы вполне можете оказаться в сценарии перерыва в памяти. Конечно, мне неизвестно, какая другая память выделяется приложением, в котором вы запускаете этот код.

Попробуйте тот же код на том же устройстве с меньшим изображением. Вы должны увидеть, что он работает нормально.

Ваши утечки Gdi обрабатывают, оборачивают поток и растровое изображение в предложениях Using.

Private Sub Button3_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button3.Click

    using ms As New IO.MemoryStream
        using bm As New Bitmap("\Application Data\imgs\IMG22.jpg")
            bm.Save(ms, Drawing.Imaging.ImageFormat.Jpeg)
        end using
    end using

End Sub
Другие вопросы по тегам