Форум программистов, компьютерный форум, киберфорум
Программирование Android
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.83/12: Рейтинг темы: голосов - 12, средняя оценка - 4.83
7 / 7 / 1
Регистрация: 20.04.2013
Сообщений: 666

Изменить код работы с Bitmap в связи с OutOfMemoryError

09.08.2013, 16:47. Показов 2609. Ответов 12
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Прочитал статью ( http://habrahabr.ru/post/161027/#habracut ) и хотел бы изменить свой код, так как в данный момент приложение испытывает OutOfMemoryError.

У меня есть код:
Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
@Override
        protected HashMap<String, Object> doInBackground(
                HashMap<String, Object>... hm) {
 
            InputStream iStream = null;
            String imgUrl = (String) hm[0].get("imageLogo_path");
            int position = (Integer) hm[0].get("position");
 
            URL url;
            try {
                url = new URL(imgUrl);
                HttpURLConnection urlConnection = (HttpURLConnection) url
                        .openConnection();
                urlConnection.connect();
                iStream = urlConnection.getInputStream();
                File cacheDirectory = getBaseContext().getCacheDir();
                File tmpFile = new File(cacheDirectory.getPath() + "/wpta_"
                        + position + ".png");
                FileOutputStream fOutStream = new FileOutputStream(tmpFile);
                Bitmap b = BitmapFactory.decodeStream(iStream);
                b.compress(Bitmap.CompressFormat.PNG, 100, fOutStream);
                fOutStream.flush();
                fOutStream.close();
 
                HashMap<String, Object> hmBitmap = new HashMap<String, Object>();
                hmBitmap.put("imageLogo", tmpFile.getPath());
                hmBitmap.put("position", position);
                return hmBitmap;
 
            } catch (Exception e) {
                e.printStackTrace();
            }
            return null;
        }
а в статье имеется пример:
Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
InputStream in = ... //Ваш InputStream
BitmapFactory.Options o = new BitmapFactory.Options();
o.inJustDecodeBounds = true;
BitmapFactory.decodeStream(in, null, o);
in.close();
int origWidth = o.outWidth; //исходная ширина 
int origHeight = o.outHeight; //исходная высота 
int bytesPerPixel = 2 //соответствует RGB_555 конфигурации
int maxSize = 480 * 800 * bytesPerPixel; //Максимально разрешенный размер Bitmap
int desiredWidth = …; //Нужная ширина
int desiredHeight = …; //Нужная высота
int desiredSize = _ desiredWidth * _ desiredHeight * bytesPerPixel; //Максимально разрешенный размер Bitmap для заданных width х height
if (desiredSize < maxSize) maxSize = desiredSize;
int scale = 1; //кратность уменьшения
int origSize = origWidth * origHeight * bytesPerPixel;
//высчитываем кратность уменьшения
if (origWidth > origHeight) {
    scale = Math.round((float) origHeight / (float) desiredHeight);
} else {
    scale = Math.round((float) origWidth / (float) desiredWidth);
}
 
o = new BitmapFactory.Options();
o.inSampleSize = scale;
o.inPreferredConfig = Config.RGB_565;
            
in = … //Ваш InputStream. Важно - открыть его нужно еще раз, т.к второй раз читать из одного и того же InputStream не разрешается (Проверено на ByteArrayInputStream и FileInputStream).
Bitmap bitmap = BitmapFactory.decodeStream(in, null, o); //Полученный Bitmap
но как я не пытался, совместить код у меня не получается. Листвью с записями отображается но без картинок. Сыпятся разные ошибки.
- resolveUri failed on bad bitmap uri: /data/data/com.androidcompany.projectmy/cache/wpta_0.png
- SkImageDecoder::Factory returned null
а иногда и вовсе не запускается крошится.

проверял папку кеша, а она пустая.

Помогите всё сделал правильно, чтобы работало. Может я что-то упускаю...
0
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
09.08.2013, 16:47
Ответы с готовыми решениями:

Ошибка OutOfMemoryError при работе с Bitmap.createBitmap
Привет всем. Прошу подскажите в чем проблема. Имеется проект на гихабе -...

java.lang.OutOfMemoryError: bitmap size exceeds VM budget
Программирую под андроид. Ошибка выскакивает здесь: photoArray=new Bitmap; ...

OutOfMemoryError после 48-50 часов работы программы.
Добрый день! Существует такая проблема: программа, написанная на java должна запускаться периодически и выполнять определенные операции с...

12
Android Developer
 Аватар для Wenceslaus
131 / 131 / 6
Регистрация: 05.07.2013
Сообщений: 205
09.08.2013, 18:55
После работы с Bitmap вызывайте bmp.recycle(); Это раз. Второе: к чему такие сложности? Замените BitmapFactory обычной записью в файл на прямую и все проблемы отпадут:
Java
1
2
3
4
5
6
7
8
 int read = 0;
 byte[] bytes = new byte[1024];
 
 while ((read = iStream.read(bytes)) != -1) {
 fOutStream.write(bytes, 0, read);
 }
 iStream.close();
 fOutStream.close();
Третье, CacheDir нужно использовать с большой осторожностью, ибо место ограничено (несколько мб), а сама она не очищается. Не по православному это. Используйте ExternalStorageDirectory.
И последнее, вы всё это выводите в ListView? Почему не использовать небезызвестные LazyList или UniversalImageLoader?
1
7 / 7 / 1
Регистрация: 20.04.2013
Сообщений: 666
09.08.2013, 19:43  [ТС]
да всё вывожу в ListView. Использую всё так потому, что изначально было так сделано, а чтоб переделать - это будет не просто.

Добавлено через 5 минут
Цитата Сообщение от Wenceslaus Посмотреть сообщение
После работы с Bitmap вызывайте bmp.recycle(); Это раз. Второе: к чему такие сложности?
в связи с OutOfMemoryError. Хочу ужимать качество. Чтобы меньше весели фотки.

Цитата Сообщение от Wenceslaus Посмотреть сообщение
Замените BitmapFactory обычной записью в файл на прямую и все проблемы отпадут:
заменил, да работает. Но а чем оно отличается от того что у меня было???
0
Android Developer
 Аватар для Wenceslaus
131 / 131 / 6
Регистрация: 05.07.2013
Сообщений: 205
09.08.2013, 20:16
Цитата Сообщение от Stylish2013 Посмотреть сообщение
Но а чем оно отличается от того что у меня было???
Тем, что используя BitmapFactory вы грузите всё изображение в память (+ забываете его выгрузить), а записывая на прямую, вы держите в памяти только 1024 (new byte[1024]) байта, 1 Кб. Посему никаких OutOfMemoryError быть не может.
0
7 / 7 / 1
Регистрация: 20.04.2013
Сообщений: 666
09.08.2013, 20:32  [ТС]
Тем, что используя BitmapFactory вы грузите всё изображение в память (+ забываете его выгрузить), а записывая на прямую, вы держите в памяти только 1024 (new byte[1024]) байта, 1 Кб. Посему никаких OutOfMemoryError быть не может.

да сейчас таких проблем нет. Но у меня притормаживает при скролинге из за записи в файл это может быть?
0
1162 / 986 / 1
Регистрация: 28.06.2012
Сообщений: 3,462
09.08.2013, 21:27
http://developer.android.com/t... itmap.html
0
 Аватар для verylazy
462 / 462 / 71
Регистрация: 26.02.2013
Сообщений: 1,263
09.08.2013, 21:38
по этой ссылке пишут как делать маленькие превьюшки, а как быть с разными дисплеями?
100 на 100 пикселей на телефоне и на топовом планшете будут разного размера
получается что либо все в абсолютных координатах и размерах, либо везде пересчитывать по какой-то формуле?
0
1162 / 986 / 1
Регистрация: 28.06.2012
Сообщений: 3,462
09.08.2013, 22:48
verylazy, используйте weight

Добавлено через 35 секунд
+ http://developer.android.com/t... reens.html
1
 Аватар для verylazy
462 / 462 / 71
Регистрация: 26.02.2013
Сообщений: 1,263
09.08.2013, 23:11
хорошая ссылка, я до нее еще не дочитал

Вот к примеру есть 10 фотографий в jpg, которые лежат на карте памяти. Как их отобразить на экране? Я пока дошел только до вот такого способа
Java
1
img.setImageBitmap(BitmapFactory.decodeFile("путь и имя файла"));
при этом все равно вычитывается весь файл и битмап занимает место в памяти равное Ш*В*4 картинка 640*480 занимает 1.2 метра примерно.
И как тут мне поможет weight? Не могу пока уложить это в голове.
0
1162 / 986 / 1
Регистрация: 28.06.2012
Сообщений: 3,462
09.08.2013, 23:59
Цитата Сообщение от verylazy Посмотреть сообщение
при этом все равно вычитывается весь файл и битмап занимает место в памяти равное Ш*В*4 картинка 640*480 занимает 1.2 метра примерно.
И как тут мне поможет weight? Не могу пока уложить это в голове.
для этого самая первая моя ссылка.
1
 Аватар для verylazy
462 / 462 / 71
Регистрация: 26.02.2013
Сообщений: 1,263
10.08.2013, 08:57
ааа, все понял!
утро - вечера мудреннее, спасибо
0
7 / 7 / 1
Регистрация: 20.04.2013
Сообщений: 666
10.08.2013, 12:20  [ТС]
Цитата Сообщение от Stylish2013 Посмотреть сообщение
Но у меня притормаживает при скролинге из за записи в файл это может быть?
ответьте пожалуйста прямо если можно на вопрос? из ссылки:
Цитата Сообщение от V0v1k Посмотреть сообщение
http://developer.android.com/trainin...ad-bitmap.html
ответа не выявил.
0
Android Developer
 Аватар для Wenceslaus
131 / 131 / 6
Регистрация: 05.07.2013
Сообщений: 205
12.08.2013, 11:30
Stylish2013, отвечу я, если никто не против. При скроллинге притормаживает не из-за записи в файл (хотя это косвенно связано), а из-за того, что загружаемые изображения слишком велики и затрачивается длительное время и много ресурсов на их обработку и отображение. Чтобы этого не происходило вам V0v1k посоветовал прочесть эту ссылку, где и описано, как уменьшить затраты на отображение изображения (конкретно решение: уменьшить размер загружаемого в ListVeiw изображения). Код и подробное описание по ссылке выше.
2
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
12.08.2013, 11:30
Помогаю со студенческими работами здесь

Возможно в Qt creator изменить код программы, во время ее работы?
Всем добрый вечер,я хочу достать функции Qt , ln, exp , скобки и тд. В программу вводится через lineEdit : ln или exp , программа...

Изменить размер BitMap
Здравствуйте Для создания Bitmap иного размера можно использовать : Bitmap NewBitmap = new Bitmap(LastBitmap, new Size(..., ...)); ...

Изменить размер изображения не используя класс Bitmap
Здравствуйте! Можно ли как-то изменить размер изображения не используя класс Bitmap? При использовании Bitmap Bitmap tmpFile = new...

Как изменить несколько битов в изображение в формате Bitmap
Задача в следующем. Мне нужно например поменять цвет некоторых битов в картинке которая загружена на форму. Например в C++ Builder есть...

Разрезать bitmap с возможностью работы отдельно с каждым куском
Подскажите, пожалуйста, как bitmap разбить на несколько равных кусков с возможностью работать с каждым куском отдельно? Уже всё перерыл, не...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
13
Ответ Создать тему
Новые блоги и статьи
Реалии
Hrethgir 01.03.2026
Нет, я не закончил до сих пор симулятор. Эта задача сложнее. Не получилось уйти в плавсостав, но оно и к лучшему, возможно. Точнее получалось - но сварщиком в палубную команду, а это значит, в моём. . .
Ритм жизни
kumehtar 27.02.2026
Иногда приходится жить в ритме, где дел становится всё больше, а вовлечения в происходящее — всё меньше. Плотный график не даёт вниманию закрепиться ни на одном событии. Утро начинается с быстрых,. . .
SDL3 для Web (WebAssembly): Сборка библиотек: SDL3, Box2D, FreeType, SDL3_ttf, SDL3_mixer и SDL3_image из исходников с помощью CMake и Emscripten
8Observer8 27.02.2026
Недавно вышла версия 3. 4. 2 библиотеки SDL3. На странице официальной релиза доступны исходники, готовые DLL (для x86, x64, arm64), а также библиотеки для разработки под Android, MinGW и Visual Studio. . . .
SDL3 для Web (WebAssembly): Реализация движения на Box2D v3 - трение и коллизии с повёрнутыми стенами
8Observer8 20.02.2026
Содержание блога Box2D позволяет легко создать главного героя, который не проходит сквозь стены и перемещается с заданным трением о препятствия, которые можно располагать под углом, как верхнее. . .
Конвертировать закладки radiotray-ng в m3u-плейлист
damix 19.02.2026
Это можно сделать скриптом для PowerShell. Использование . \СonvertRadiotrayToM3U. ps1 <path_to_bookmarks. json> Рядом с файлом bookmarks. json появится файл bookmarks. m3u с результатом. # Check if. . .
Семь CDC на одном интерфейсе: 5 U[S]ARTов, 1 CAN и 1 SSI
Eddy_Em 18.02.2026
Постепенно допиливаю свою "многоинтерфейсную плату". Выглядит вот так: https:/ / www. cyberforum. ru/ blog_attachment. php?attachmentid=11617&stc=1&d=1771445347 Основана на STM32F303RBT6. На борту пять. . .
Камера Toupcam IUA500KMA
Eddy_Em 12.02.2026
Т. к. у всяких "хикроботов" слишком уж мелкий пиксель, для подсмотра в ESPriF они вообще плохо годятся: уже 14 величину можно рассмотреть еле-еле лишь на экспозициях под 3 секунды (а то и больше),. . .
И ясному Солнцу
zbw 12.02.2026
И ясному Солнцу, и светлой Луне. В мире покоя нет и люди не могут жить в тишине. А жить им немного лет.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru