Как стать автором
Обновить

Комментарии 24

Что касается OutOfMemory:
До 3.0 данные картинки хранятся в нативном коде, можно использовать вот этот хак: habrahabr.ru/post/139717/ и забить ими всю доступную память на устройстве :)
В 3.0 и выше данные лежат прямо в виде byte[] в самом Bitmap — тут уже, к сожалению, так обдурить DVM не получится, но можно прописать приложению атрибут largeHeap в манифесте — на некоторых устройствах ему тогда дадут дофига памяти (например, на SGS3 получается 256 Мб).
Спасибо за дополнение
Спасибо за статью. Думаю, многим окажется полезной данная информация.

4) Гарантируется, что декодер вернет уменьшенное изображение без OutOfMemoryError

Это, наверное, если надо декодировать всего одно изображение. На практике же не всегда так радужно получается. code.google.com/p/android/issues/detail?id=8488
Да, конечно, можно держать в памяти несколько изображений 480х800 и забить память. Однако, какой профит держать столько больших изображений в памяти? Если взять за пример галерею, то в один момент времени отображается одна большая картинка. Можно конечно делать прелоад в память соседних картинок для более быстрого отображения, но нужно представлять себе сколько памяти вы можете на это потратить, отталкиваясь от heap size конкретного устройства.
Ну тот же ViewPager, как минимум, создает заранее View слева и справа. Плюс, если картинки пережимаются или загружаются из интернета, то неплохо бы было кешировать хотя бы часть.
Кэширование это тема для целой отдельной статьи. Если интересно кому-нибудь, могу написать пост про CacheManager, который умеет загружать картинки из нета и кешировать их в файловом кэшe и в памяти на основе алгоритма Lru и генерировать превьюшки разных размеров, в том числе с определением лица.
Было бы здорово (:
90, 180, 270 и -1 выносят мозг. Ну почему нельзя было использовать 0?
На самом деле там есть и 0 градусов, а -1 это ошибочное состояние. Сейчас исправлю, спасибо!
Ну по крайней мере в случае ExifInterface.ORIENTATION_NORMAL возвращается -1
Исправил
Спасибо, очень полезная и актуальная статья. Пятой точкой я в-принципе чувствую, что там нужно написать в классах ResizeMode и ScaleMode, но все-таки хотелось бы увидеть полный листинг.
Всё правильно, сейчас добавлю эти два энума и заодно опишу режимы, которые они задают.
4) Гарантируется, что декодер вернет уменьшенное изображение без OutOfMemoryError


Это кем гарантируется? Если картинок много, то даже хаки не работают — кончается память. Я в результате остановился на таком решении: мониторю состояние памяти перед каждым декодированием картинки, если память занята > 50%( эмпирическое значение), то очищаю все уже декидорованные битмапы(через recycle()) и декодирую по необходимости заново.
Я постарался изолировать пример от боевых условий, чтобы был понятен смысл.

А в боевых условиях конечно нужно еще и контролировать состояние памяти. Я могу подсказать решение попроще — LruCache (http://developer.android.com/reference/android/util/LruCache.html). Задаем лимит кэша (в зависимости от конкретного heap size например) и можем быть спокойны. LruCache есть также в support library v4.
Ну боевые условия-то самое оно. А про кэш спасибо, натыкался на него и забыл. Попробую.
А может кто-нибудь может посоветовать библиотеку, которая:
1) Умеет выбирать картинку из галереи
2) Получать фотографию от камеры
3) Решает проблемы с нужным размером и автоповоротом
Я написал своё решение, но у меня мало ресурсов для тестирования. Так что я предпочёл бы стороннее, протестированное решение.
Тоже интересно было бы узнать. Самому пришлось изобретать свой велосипед с помощью гугла и stackoverflow. В плане тестирования оказалось вполне достаточно эмуляторов и пары девайсов с 2 и 4м андроидом
Я тоже так думал. А потом оказалось, что на какой-то модели телефона фото неправильно переворачиваются. Подробностей уже не помню, давно было.
В консоли Google Play написано, что мое приложение поддерживает чуть более 2000 устройств. Это нереальное количество для тестирования. Поэтому протестируйте на паре тройке популярных моделях. Для остальных телефонов исправляйте ошибки по фидбеку. Я другого варианта не вижу.

P.S. Если подумать, то и для сторонней библиотеки нет никакой гарантии, что она протестирована на всех устройствах.
А как быть в том случае, когда изображение загружается из интернета? Нежелательно второй раз открывать подключение к серверу и ждать загрузки изображения.
Конечно, загрузка одного и того же изображения из нета съест и заряд батареи и терпение пользователя. Поэтому изображение можно и нужно сохранить на SD.
Вы предлагаете вначале кэшировать изображение в полном размере, а затем уже извлекать данные оттуда?
После загрузки картинки с нета у вас на руках есть byte[]. И тут уже сами думайте как оптимально с ним работать. У меня, например, с сервера приходят уже оптимизированные картинки и я их сразу сохраняю в файловый кеш и из того же byte[] делаю превьюшку. Т.е с одним и тем же byte[] можно проделать разные операции, смотря что требуют условия задачи.
Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации

Истории