Комментарии 24
Что касается OutOfMemory:
До 3.0 данные картинки хранятся в нативном коде, можно использовать вот этот хак: habrahabr.ru/post/139717/ и забить ими всю доступную память на устройстве :)
В 3.0 и выше данные лежат прямо в виде byte[] в самом Bitmap — тут уже, к сожалению, так обдурить DVM не получится, но можно прописать приложению атрибут largeHeap в манифесте — на некоторых устройствах ему тогда дадут дофига памяти (например, на SGS3 получается 256 Мб).
До 3.0 данные картинки хранятся в нативном коде, можно использовать вот этот хак: habrahabr.ru/post/139717/ и забить ими всю доступную память на устройстве :)
В 3.0 и выше данные лежат прямо в виде byte[] в самом Bitmap — тут уже, к сожалению, так обдурить DVM не получится, но можно прописать приложению атрибут largeHeap в манифесте — на некоторых устройствах ему тогда дадут дофига памяти (например, на SGS3 получается 256 Мб).
0
Спасибо за статью. Думаю, многим окажется полезной данная информация.
Это, наверное, если надо декодировать всего одно изображение. На практике же не всегда так радужно получается. code.google.com/p/android/issues/detail?id=8488
4) Гарантируется, что декодер вернет уменьшенное изображение без OutOfMemoryError
Это, наверное, если надо декодировать всего одно изображение. На практике же не всегда так радужно получается. code.google.com/p/android/issues/detail?id=8488
0
Да, конечно, можно держать в памяти несколько изображений 480х800 и забить память. Однако, какой профит держать столько больших изображений в памяти? Если взять за пример галерею, то в один момент времени отображается одна большая картинка. Можно конечно делать прелоад в память соседних картинок для более быстрого отображения, но нужно представлять себе сколько памяти вы можете на это потратить, отталкиваясь от heap size конкретного устройства.
+1
Ну тот же ViewPager, как минимум, создает заранее View слева и справа. Плюс, если картинки пережимаются или загружаются из интернета, то неплохо бы было кешировать хотя бы часть.
0
Кэширование это тема для целой отдельной статьи. Если интересно кому-нибудь, могу написать пост про CacheManager, который умеет загружать картинки из нета и кешировать их в файловом кэшe и в памяти на основе алгоритма Lru и генерировать превьюшки разных размеров, в том числе с определением лица.
+1
90, 180, 270 и -1 выносят мозг. Ну почему нельзя было использовать 0?
0
Спасибо, очень полезная и актуальная статья. Пятой точкой я в-принципе чувствую, что там нужно написать в классах ResizeMode и ScaleMode, но все-таки хотелось бы увидеть полный листинг.
0
4) Гарантируется, что декодер вернет уменьшенное изображение без OutOfMemoryError
Это кем гарантируется? Если картинок много, то даже хаки не работают — кончается память. Я в результате остановился на таком решении: мониторю состояние памяти перед каждым декодированием картинки, если память занята > 50%( эмпирическое значение), то очищаю все уже декидорованные битмапы(через recycle()) и декодирую по необходимости заново.
0
Я постарался изолировать пример от боевых условий, чтобы был понятен смысл.
А в боевых условиях конечно нужно еще и контролировать состояние памяти. Я могу подсказать решение попроще — LruCache (http://developer.android.com/reference/android/util/LruCache.html). Задаем лимит кэша (в зависимости от конкретного heap size например) и можем быть спокойны. LruCache есть также в support library v4.
А в боевых условиях конечно нужно еще и контролировать состояние памяти. Я могу подсказать решение попроще — LruCache (http://developer.android.com/reference/android/util/LruCache.html). Задаем лимит кэша (в зависимости от конкретного heap size например) и можем быть спокойны. LruCache есть также в support library v4.
0
А может кто-нибудь может посоветовать библиотеку, которая:
1) Умеет выбирать картинку из галереи
2) Получать фотографию от камеры
3) Решает проблемы с нужным размером и автоповоротом
Я написал своё решение, но у меня мало ресурсов для тестирования. Так что я предпочёл бы стороннее, протестированное решение.
1) Умеет выбирать картинку из галереи
2) Получать фотографию от камеры
3) Решает проблемы с нужным размером и автоповоротом
Я написал своё решение, но у меня мало ресурсов для тестирования. Так что я предпочёл бы стороннее, протестированное решение.
0
Тоже интересно было бы узнать. Самому пришлось изобретать свой велосипед с помощью гугла и stackoverflow. В плане тестирования оказалось вполне достаточно эмуляторов и пары девайсов с 2 и 4м андроидом
0
Я тоже так думал. А потом оказалось, что на какой-то модели телефона фото неправильно переворачиваются. Подробностей уже не помню, давно было.
0
В консоли Google Play написано, что мое приложение поддерживает чуть более 2000 устройств. Это нереальное количество для тестирования. Поэтому протестируйте на паре тройке популярных моделях. Для остальных телефонов исправляйте ошибки по фидбеку. Я другого варианта не вижу.
P.S. Если подумать, то и для сторонней библиотеки нет никакой гарантии, что она протестирована на всех устройствах.
P.S. Если подумать, то и для сторонней библиотеки нет никакой гарантии, что она протестирована на всех устройствах.
0
А как быть в том случае, когда изображение загружается из интернета? Нежелательно второй раз открывать подключение к серверу и ждать загрузки изображения.
0
Конечно, загрузка одного и того же изображения из нета съест и заряд батареи и терпение пользователя. Поэтому изображение можно и нужно сохранить на SD.
0
Вы предлагаете вначале кэшировать изображение в полном размере, а затем уже извлекать данные оттуда?
0
После загрузки картинки с нета у вас на руках есть byte[]. И тут уже сами думайте как оптимально с ним работать. У меня, например, с сервера приходят уже оптимизированные картинки и я их сразу сохраняю в файловый кеш и из того же byte[] делаю превьюшку. Т.е с одним и тем же byte[] можно проделать разные операции, смотря что требуют условия задачи.
0
Зарегистрируйтесь на Хабре, чтобы оставить комментарий
Получение изображения нужного размера без OutOfMemoryError + автоповорот согласно EXIF orientation