Но однажды я столкнулся с тем, что все библиотеки для загрузки изображений, которые я посмотрел либо работают с изображениями недостаточно эффективно, либо их трудно переделать под конкретную задачу. Я честно решил поконтрибьютить в одну из библиотек, которая на первый взгляд выглядела неплохо. Но, увы и ах, с прискорбием заметил что аналогичные попытки оптимизации данной библиотеки безуспешно предпринимаются с 2014 года.
Так как человек я по натуре ленивый — решил пойти проторенным путем — открыл пример от гугла Loading Large Bitmaps Efficiently и решил вырезав из него все ненужное — получить с одной стороны легко расширяемую, а с другой стороны максимально эффективную библиотеку.
Так как кто как не эти чуваки лучше знают как грузить битмапы?
Так и получился Малевич:
Спойлер:
malevich.load(mImageUrl).into(mImageView);
Вырезав, все ненужное и поправив глючки (их было чертовски мало) я начал добавлять нужное)
Наверное не сложно догадаться, какой библиотекой я вдохновлялся упрощая синтаксис.
Но давайте собственно к библиотеке.
Есть два режима использования.
Режим для гагар:
// init
Malevich malevich = new Malevich.Builder(this).build();
// use
malevich.load(mImageUrl).into(mImageView);
//где mImageUrl - Bitmap или BitmapDrawable или Resource id или HttpUrl или Путь к файлу
И режим для тех, кому за 30:
Memory and disk caching params
ImageCache.ImageCacheParams cacheParams = new ImageCache.ImageCacheParams(this, "dir");
cacheParams.memoryCacheEnabled = true; //Enable memory cache
cacheParams.setMemCacheSizePercent(0.4f); //Percent of available memory for cache
cacheParams.compressQuality = 90; // Compress quality
cacheParams.compressFormat = Bitmap.CompressFormat.PNG; // Compress format
cacheParams.diskCacheEnabled = true; // Use disk cache
cacheParams.diskCacheSize = 10485760; // Disk cache size
Malevich Builder
malevich = new Malevich.Builder(this)
.debug(true) // write log
.maxSize(1024) // max size of image in px
.LoadingImage(R.drawable.some) // preloader image or recource
.CacheParams(casheParams) // custom cache
.build();
Loading image
Transform image after loading with prebuild utils or custom method:
malevich.load(url).width(mItemHeight).height(mItemHeight).imageDecodedListener(new Malevich.ImageDecodedListener() {
@Override
public Bitmap onImageDecoded(String data, int reqWidth, int reqHeight, Bitmap bitmap) {
// Get squared bitmap and transform it to circle
return Malevich.Utils.getSquaredCircleBitmap(bitmap,reqWidth);
}
}).into(imageView);
Но в общем и целом, целью проекта не было сделать пикассо или глайд на гугловском движке. Я добавил только самые необходимые утилиты, постоянно использующиеся в нелегкой жизни фрилансера — дай квадрат из картинки, дай круг и т.п. Так как хотелось сохранить легкую расширяемость и не превратиться в какую-нибудь прости господи фреску от сами знаете кого.
Да, предмет моей особой гордости это то, что библиотека содержит меньше десятка классов и 0 (Зиро) зависимостей.
Ну и всякие формальности:
— настраиваемый, нежнейший лру кэш в памяти
— отключаемый дисковый кэш
— перекрытие событий загрузки, ошибок
— управление потоками
— няшные утилиты, удобный билдер
— единственная библиотека эффективно переиспользующая память согласно лучшим рекомендациям от Гугла)
В общем, если вам когда нибудь придется грузить тонны картинок в хитро закрученном воркфлоу со всякими кастомными штуками — вспомните о Малевиче.
Ссылка на гитхаб: github.com/recoilme/malevich
Буду рад контрибьюторам!
Комментарии (15)
0leGG
10.07.2015 01:00+6Дайте угадаю — вместо всех картинок чёрные квадраты рисуются?
recompileme Автор
10.07.2015 10:40+2была идея так пошутить если не удалось загрузить картинку, но сдержался)
Evgenij_Popovich
13.07.2015 12:40Не нашел в коде поддержки EXIF Orientation. Вероятно, кому-то эта опция будет полезной.
Bringoff
13.07.2015 21:13Использую Glide, пока все устраивает. Я склонен верить гуглу, который её порекомендовал. Возможно, «нежнейший лру кэш» меня будет прельщать, когда мне будет за 30, но тогда и android-а может уже не быть :D
recompileme Автор
21.07.2015 11:09А где он ее порекомендовал, можно ссылку?
Bringoff
21.07.2015 11:19Как минимум, вот так.
recompileme Автор
21.07.2015 11:31Это не рекомендация, это вполне типичный для гугла фейл. Вместо того чтобы написать свой удобный врапер над urlConnection и менеджер загрузки битмапов — юзаются левые Basic HTTP Client / Glide в проекте — примере. Стыдно.
BOOMik
14.07.2015 23:24Интересно попробовать… Какая минимальная поддерживаемая версия API?
И залить бы в MAVEN…recompileme Автор
21.07.2015 11:07Тестил на 11, поэтому поставил ее. Но заглушки в коде стоят и для глючков второго андроида, так что по идее должно работать на любом апи одинаково.
danikula
17.07.2015 15:02Не совсем понял, в чем преимущества над уже хорошо зарекомендовавшими себя решениями (fresco, UIL, Picasso)? В минимализме или еще в чем-то? Хотелось бы услышать развернутое сравнение с конкурентами: наличие/отсутствие фич, перфоманс, размер и пр.
recompileme Автор
21.07.2015 11:04+1Все библиотеки работают по устоявшейся схеме, которая выглядит примерно так:
Принципиальных отличий между ними нет, поэтому можно говорить только о каких то нюансах и субъективном мнении.
— fresco
Во первых у меня предвзятое отношение к продуктам данной компании. Фейсбук, пожалуй единственное приложение, которое умудряется глючить и лагать среди равных себе по охвату аудитории на моем нексус 5. Сообщение «Отстутствует соедениение» — стало настолько привычным, что я уже даже не кликаю по уведомлениям. Вероятность корректного получения токена при интеграции с фесбук, была вычисленна экспериментально и составляет 90%. Т.е. в 1 из 10 случаев вместо токена вернется ничто. Но если отбросить предвзятость:
+ поддержка webp и gif из коробки
+ хитрое выделение памяти
— совершенно некастомизируемо.
— исходный код нечитаем
Используется кастомная вьюха для рендеринга битмапов, которая хоть и является наследницей imageview — не переиспользуема со стороны. Например в процессе загрузки вам нужно рисовать кружок с процентом загрузки как принять в iOs — вы не можете тупо написать setBitmap вьюхе, потому что это сломает их процесс: frescolib.org/docs/gotchas.html#_
— picasso
+ простой интерфейс
— слабая функциональность
— неэффективное управление памятью ( не используются inBitmaps)
Подходит только для примитивных задач. Нельзя ни поставить загрузку на паузу, ни задать размеры кешей, да практически ничего нельзя. Насколько я понял проект заброшен и Джейк Вартсон переключился на Glide
— UIL
+ хороший компромисс между функциональностью и простотой
— неэффективное управление памятью (предположительно)
Неплохое развитие идей Федора Власова, если честно глубоко не смотрел, потому что оригинал Федора мне ближе, его легче было подстраивать под себя
Вобщем я позиционирую малевича как нечто среднее между uil и picasso. По хорошему надо бы дописать функционала, не изгадив простоту, и будет неплохая библиотека. Пока она чуть лучше picasso, но уступает по функционалу и количеству фич всем остальным.
maeln0r
Спасибо, большое. То, что надо!