Как Android преобразует размеры ресурсов
Размер APK файла можно уменьшить, выкинув «ненужные» LDPI ресурсы, Android все равно умеет генерировать их на лету из MDPI. Но что будет если убрать еще и MDPI каталог? И как именно будет произведена свертка: усреднением или более дешевым выбрасыванием пикселей? Перескочит ли Android через один шаг чтобы произвести потенциально более простое преобразование HDPI → LDPI? Как именно происходит уменьшение картинок в разных случаях? Чтобы ответить на эти вопросы я провел небольшой тест.
Теория
Каталоги ldpi-mdpi-hdpi-xhdpi… попарно отстоят друг от друга на ~33.(3) или 50%, то есть MDPI ресурс должен быть примерно в 1.33 раза больше LDPI, а HDPI — уже в 2 раза больше. При преобразованиях 2→1 и 4→1 теоретически возможны «дешевые» отбрасыванием каждого второго пикселя, при переходе 1.5→1 теоретически возможна оптимизация с отбрасыванием одного пикселя из трех, а при переходе 1.33→1 — одного из четырех, осталось проверить какие оптимизации и алгоритмы использует Android в действительности.
Методика тестирования
Создаем файл с повторяющимся паттерном из разноцветных полос шириной в один и два пикселя, чтобы проще было видеть результат свертки. Паттерны выглядят так
▣▣▣▣▣▣▣▣ и ▣▣▣▣▣▣▣▣
и размещены со смещением 0, 1 и 2 пикселя от границы (паттерны однонаправленные, так как вертикальная и горизонтальные свертки очевидно должны использовать одинаковый алгоритм).
Помещаем картинку (одну и ту же) в каталоги LDPI, MDPI и т.д под разными именами и на каждой копии рисуем «водяной знак» обозначающий каталог, в котором она находится, чтобы знать, откуда Android взял исходник для преобразования. Отображаем картинки изо всех (MDPI-XXXDPI) каталогов на разрешениях от LDPI до XXHDPI. Смотрим под лупой, что же получилось, и отвечаем на вопросы.
Одинаков ли алгоритм свертки для переходов 1.5→1 и 1.33→1?
Очевидно нет, можно сравнить, как выглядит паттерн из каталога HDPI на MDPI экране и паттерн MDPI на LDPI
Исходники на GitHub
Спасибо за внимание!