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 пикселей. Детали изображения:

Dimension: 1536x2048 Horizontal Resolution: 72dpi Horizontal Resolution: 72dpi Bit depth: 24 Resolution unit: 2 Color representation: sRGB -

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

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

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

Solution and explanation of the problem Ну а после тестирования кое-что стало настоящей проблемой - не утечка памяти, как сказал @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, плохая идея. Большое спасибо всем, кто нашел время, чтобы прочитать мою проблему, и особенно тем, кто публикует свой ответ.

Solution (if you need to show the image in a picture box):

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

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

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

About Chris Tacke Я просто понимаю, что автор поста об ImageHelper и соучредителе OpenNetCF здесь, в stackoverflow, вот его профиль:https://stackoverflow.com/users/13154/ctacke

Ответы на вопрос(2)

Решение Вопроса

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

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

1500 * 1500 * 4 = 9 МБ.

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

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

 14 июн. 2012 г., 19:03
Если вам просто нужно передать jpeg в виде байтового массива, почему бы вам просто не использовать объект FileStream для непосредственного считывания байтовых данных из файла, а не для распаковки сначала в растровое изображение?
 Allende14 июн. 2012 г., 19:36
вероятно, потому что я понятия не имею, что я делаю, ну, в общем, позвольте мне попробовать, но в то же время вы были правы, я только что проверил изображение размером 400x400, и исключение не вышло.
 Allende14 июн. 2012 г., 18:02
Ооооооооооооооо, ну я кое-что прочитал здесьlink  Позвольте мне попробовать с меньшим изображением, но тогда нет никакого способа сделать это, мне нужно передать изображение в байтовый массив, чтобы сохранить его в базе данных, на самом деле это работает на ПК (я думаю, потому что я могу злоупотреблять памяти), но я получил эту проблему на мобильном устройстве.

С помощью статьи.

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
 Allende14 июн. 2012 г., 19:38
Привет @asawyer, мне жаль, что я не был грубым, но тогда, если я хорошо понял, обернуть с использованием "quot;" объекты помогают освободить ресурсы, например, использовать метод .dispose ()? Или я все еще потерялся?
 14 июн. 2012 г., 19:00
@Allende pdriegen, вероятно, правильно, но это также могло бы помочь.
 Allende14 июн. 2012 г., 17:09
Привет, @asawyer. Oamm. Я не совсем тебя понимаю, но, даже оборачивая поток и растровое изображение (как вы показываете мне), приложение выдает то же исключение при запуске на устройстве.
 14 июн. 2012 г., 19:41
@Allendeusing преобразует его в блок try / finally, который автоматически вызываетDispose() для объекта. Среда выполнения наверняка справится с этим, но иногда вам нужно освободить ресурс как можно скорее, как в ситуациях с нехваткой памяти. В окнах потоки и растровые изображения выделяют базовые объекты ОС, которые не будут освобождены, пока GC не заберет их в какой-то момент в будущем, если вы не вызоветеDispose на них.

Ваш ответ на вопрос