Mipmap для рисования иконок

449

Начиная с Android 4.3 (Jelly Bean) мы теперь можем использовать res/mipmapпапки для хранения изображений «mipmap».

Например, Chrome для Android хранит свои значки в этих папках вместо обычных res/drawableпапок.

Чем эти изображения в формате MIPPAM отличаются от других известных изображений для рисования?

Я вижу, что в моем манифесте мы используем @mipmap/классификатор вместо @drawable/, который имеет смысл, учитывая имя папки ресурса:

<activity
    android:name=".MipmapDemp"
    android:icon="@mipmap/ic_launcher" />

Ссылки:

Документ API Android 4.3 содержит следующее:

Использование mip-карты в качестве источника для вашего растрового или растрового изображения - это простой способ обеспечить качественное изображение и различные масштабы изображения, что может быть особенно полезно, если вы ожидаете, что ваше изображение будет масштабироваться во время анимации.

В Android 4.2 (уровень API 17) добавлена ​​поддержка mipmaps в классе Bitmap - Android меняет изображения mip в своем Bitmap, когда вы указали источник mipmap и включили setHasMipMap (). Теперь в Android 4.3 вы также можете включить mipmaps для объекта BitmapDrawable, предоставив актив mipmap и установив атрибут android: mipMap в файле ресурсов растрового изображения или вызвав hasMipMap ().

Я не вижу там ничего, что помогло бы мне понять.


Ресурсы XML Bitmap имеют android:mipMapсвойство:

Boolean. Включает или отключает подсказку mipmap. Смотрите setHasMipMap () для получения дополнительной информации. Значением по умолчанию является false.

Насколько я вижу, это не относится к значкам запуска.


Был задан вопрос о группах Google ( цель названия ресурса "mipmap" ?! ), на что Romain Guy ответил:

Полезно предоставить изображение с более высоким разрешением, которое обычно рассчитывается (например, на устройстве с поддержкой mdpi Launcher может захотеть, чтобы на значке большего размера hdpi отображались ярлыки больших приложений).

Я чувствую, что это почти имеет смысл, но не совсем.

Я все еще склонен пойти с продолжением Рэнди Сугианто:

Каковы преимущества этого? Есть ли какое-нибудь руководство, как использовать mipmaps, возможно, для лучших иконок запуска?


Конечно, в Википедии есть страница для «Mipmap» , которая относится к более старой методике, изобретенной в 1983 году, которую я не совсем могу связать с текущей реализацией Android.


Должны ли мы хранить все наши значки приложений в res/mipmapпапках в эти дни, и каковы рекомендации для этих изображений MipMap?


Обновление № 1

Вот пост в блоге, который пытается объяснить это немного.

Но изображение, использованное в этом посте, показывает, что выглядит как один файл с множеством логотипов. Это не то, что я вижу в папке Chrome MipMap.

mipmap-hdpiПапка Chrome содержит три изображения. Одним из них является логотип Chrome, сам по себе.

Chrome mipmap-hdpi icon.png

Как ни странно, это 72х72, а не 48х48, что я ожидал увидеть.

Возможно, это все, что нужно для этого - нам просто нужно держать большие значки в папках mipmap?


Обновление № 2

В блоге разработчиков Android от 23.10.2014 снова подтверждается идея использования mipmapпапок для значков приложений:

Говоря о плотности экрана Nexus 6, автор пишет:

Рекомендуется размещать значки приложений в папках mipmap (не в папках drawable), поскольку они используются с разрешением, отличным от текущей плотности устройства. Например, значок приложения xxxhdpi можно использовать на панели запуска для устройства xxhdpi.


Обновление № 3

Обратите внимание, что Android Studio создает ic_launcher.pngзначки в mipmap...папках, а неdrawable... папках, в которых Eclipse использовал их для создания.


Ричард Ле Мезурье
источник

Ответы:

260

Существует два разных использования мипмапов:

  1. Для значков лаунчера при построении конкретных APK. Некоторые разработчики создают отдельные APK для каждой плотности, чтобы уменьшить размер APK. Однако некоторые программы запуска (поставляются с некоторыми устройствами или доступны в магазине Play) используют значки большего размера, чем стандартные 48dp. Пусковые установки используют getDrawableForDensity и при необходимости уменьшают, а не увеличивают, чтобы значки были высокого качества. Например, на планшете hdpi программа запуска может загрузить значок xhdpi. Поместив значок запуска в каталог mipmap-xhdpi, он не будет удален, как каталог drawable-xhdpi, при создании APK для устройств hdpi. Если вы создаете единый APK для всех устройств, это не имеет значения, так как программа запуска может получить доступ к ресурсам, доступным для извлечения, с желаемой плотностью.

  2. Фактический API MipMap из 4.3. Я не использовал это и не знаком с этим. Он не используется программами запуска проектов с открытым исходным кодом Android, и я не знаю ни о каком другом модуле запуска.

Кевин ТеслаКойл
источник
2
Итак, вы предлагаете скрипт сборки, который удаляет папки с неправильной плотностью для всех, кроме ресурсов mipmap, если я правильно понимаю?
Ричард Ле Мезурье
20
Я бы предложил просто создать один APK для всех плотностей и не беспокоиться об этом. Но да, причина, по которой каталоги mipmap иногда используются для значков средства запуска, заключается в том, что сценарии сборки (aapt --preferred-configurations) удаляют каталоги drawable- {плотность}, но не каталоги mipmap- {плотность}. Это похоже на использование ошибки, но ваша цитата из сообщения Ромена Гая и Дайаны Хэкборн на plus.google.com/105051985738280261832/posts/QTA9McYan1L показывает, что это сделано специально .
Кевин ТеслаКойл
3
так что мой типичный процесс удаления mipmap, размещения моих значков в drawables и создания одного APK идеален. Звучит так, будто mipmap нетипичен для большинства из нас, разработчиков, но навязывается всем нам.
Кто-то где-то
В документации написано: «mipmap: отрисовываемые файлы для разных плотностей значков запуска». developer.android.com/guide/topics/resources/…
активность
79

Похоже, Google обновил свои документы с тех пор, как все эти ответы, так что, надеюсь, это поможет кому-то еще в будущем :) Просто столкнулся с этим вопросом сам, создавая новый (новый новый) проект.

TL; DR: отрисовки можно удалить как часть оптимизации ресурсов, специфичных для dp. Mipmaps не будут удалены.

Различные приложения запуска домашнего экрана на разных устройствах отображают значки запуска приложений с различным разрешением. Когда методы оптимизации ресурсов приложения удаляют ресурсы из-за неиспользуемой плотности экрана, значки запуска могут выглядеть нечеткими, потому что приложение запуска должно масштабировать значок с более низким разрешением для отображения. Чтобы избежать этих проблем с отображением, приложения должны использовать mipmap/папки ресурсов для значков запуска. Система Android сохраняет эти ресурсы вне зависимости от плотности записи и гарантирует, что приложения запуска могут выбирать значки с наилучшим разрешением для отображения.

http://developer.android.com/tools/projects/index.html#mipmap )

Кадзуаки
источник
2
Это соответствует размещению по умолчанию в Android Studio при импорте графических ресурсов. Иконки запуска запускаются в mipmap; другие уходят в рисование.
Эдвард Брей
2
Кажется, что документация снова изменилась, mipmap, кажется, не существует в developer.android.com/tools/projects/index.html (несмотря на то, что другие части документации Android все еще пытаются ссылаться на нее).
Кто-то еще
28

Чем эти изображения в формате MIPPAM отличаются от других известных изображений для рисования?

Вот мои два цента в попытке объяснить разницу. Есть два случая, с которыми вы сталкиваетесь при работе с изображениями в Android:

  1. Вы хотите загрузить изображение для плотности вашего устройства, и вы собираетесь использовать его «как есть», не меняя его фактический размер . В этом случае вы должны работать с рисованными объектами, и Android даст вам наиболее подходящее изображение.

  2. Вы хотите загрузить изображение для плотности вашего устройства, но это изображение будет увеличено или уменьшено . Например, это необходимо, когда вы хотите показать значок запуска большего размера или у вас есть анимация, которая увеличивает размер изображения. В таких случаях, чтобы обеспечить наилучшее качество изображения, вы должны поместить свое изображение в папку mipmap . Что Android сделает, так это попытается взять изображение из корзины с более высокой плотностью, а не масштабировать его. Это повысит резкость (качество) изображения.

Таким образом, эмпирическое правило, чтобы решить, куда поместить ваше изображение, будет:

  • Иконки запуска всегда идут в папку mipmap .
  • Изображения, которые часто масштабируются (или сильно уменьшаются) и качество которых критично для приложения, попадают в mipmap. папку .
  • Все остальные изображения - обычные рисунки .
сергей шафаренка
источник
Значит значки в панели действий или значки для плавающей кнопки идут в mipmap?
Хуан де ла Круз
Нет, они обычные раскладные.
Сергей Шафаренко
23

Реализация mipmaps для Android в 4.3 - это именно та техника 1983 года, которая описана в статье в Википедии :)

Каждое растровое изображение набора мип-карт является уменьшенной копией основной текстуры, но с определенным сниженным уровнем детализации. Хотя основная текстура будет по-прежнему использоваться, когда представление достаточно для ее рендеринга во всех деталях, средство визуализации переключится на подходящее изображение в виде мип-карты (...) при просмотре текстуры с расстояния или с небольшим размером.

Хотя это описывается как метод для трехмерной графики (поскольку в нем упоминается «просмотр с расстояния»), оно также применимо и к 2D (переводится как «нарисовано - это меньшее пространство», то есть «уменьшен масштаб»).

Для конкретного примера Android представьте, что у вас есть представление с определенным фоном для рисования (в частности, a BitmapDrawable). Теперь вы используете анимацию, чтобы масштабировать ее до 0,15 от ее первоначального размера. Обычно для этого требуется уменьшить фоновое изображение для каждого кадра. Однако это «экстремальное» уменьшение масштаба может привести к визуальным артефактам.

Вы можете, однако, предоставить mipmap, что означает, что изображение уже предварительно отрендерено для нескольких конкретных масштабов (скажем, 1,0, 0,5 и 0,25). Всякий раз, когда анимация «пересекает» порог 0,5, вместо того, чтобы продолжать уменьшать исходное изображение размером 1,0, она переключается на изображение 0,5 и уменьшает его, что должно обеспечить лучший результат. И так далее, анимация продолжается.

Это немного теоретически, так как на самом деле это делает рендер. Согласно источнику класса Bitmap, это всего лишь подсказка, и средство визуализации может или не может соблюдать его.

/**
 * Set a hint for the renderer responsible for drawing this bitmap
 * indicating that it should attempt to use mipmaps when this bitmap
 * is drawn scaled down.
 *
 * If you know that you are going to draw this bitmap at less than
 * 50% of its original size, you may be able to obtain a higher
 * quality by turning this property on.
 * 
 * Note that if the renderer respects this hint it might have to
 * allocate extra memory to hold the mipmap levels for this bitmap.
 *
 * This property is only a suggestion that can be ignored by the
 * renderer. It is not guaranteed to have any effect.
 *
 * @param hasMipMap indicates whether the renderer should attempt
 *                  to use mipmaps
 *
 * @see #hasMipMap()
 */
public final void setHasMipMap(boolean hasMipMap) {
    nativeSetHasMipMap(mNativeBitmap, hasMipMap);
}

Я не совсем уверен, почему это было бы особенно подходящим для значков приложений, хотя. Хотя Android на планшетах, а также некоторые программы запуска (например, GEL) запрашивают значок «на одну плотность выше», чтобы показать его больше, это предполагается сделать с помощью обычного механизма (т. Е. drawable-xxxhdpi& C).

Матяш
источник
Это на самом деле не объясняет отличие от drawableпапок, которые также содержат изображения с разметкой.
Тимммм
2
На самом деле, этот ответ совершенно неверный. Только разница в том , являются ли раздели или не файлы - это не имеет ничего общего с, используется ли или нет Mipmapping (это в обоих случаях). Эта папка плохо названа; они, вероятно, должны были назвать это drawable-nostripили что-то.
Тимммм
2
Хорошее объяснение мипмапов, но ответ Казуаки на ссылку на документ в Google, похоже, подразумевает, что это на самом деле не причина.
Триларион
11

Одна вещь, которую я упомянул в другой ветке, на которую стоит обратить внимание - если вы создаете разные версии своего приложения для разных плотностей, вы должны знать о каталоге ресурсов «mipmap». Это точно так же, как «рисуемые» ресурсы, за исключением того, что он не участвует в разборке плотности при создании различных целей apk.

https://plus.google.com/105051985738280261832/posts/QTA9McYan1L

Крекер
источник
... да, действительно, как упомянул Кевин в принятом ответе. Это, кажется, было главной причиной этого.
Ричард Ле Мезурье
@RichardLeMesurier да, просто для краткости и ясности
kreker
4

Поскольку я искал разъясняющий ответ на этот вопрос, чтобы определить правильный тип значков уведомлений, я хотел бы добавить это четкое утверждение в тему. Это от http://developer.android.com/tools/help/image-asset-studio.html#saving

Примечание. Файлы значков запуска находятся в другом месте, чем другие значки. Они расположены в папке mipmap /. Все остальные файлы значков находятся в папке drawable / вашего проекта.

Стеф
источник
3

Есть два случая, с которыми вы сталкиваетесь при работе с изображениями в Android:

  1. Вы хотите загрузить изображение для плотности вашего устройства, и вы собираетесь использовать его «как есть», не меняя его фактический размер. В этом случае вы должны работать с рисованными объектами, и Android даст вам наиболее подходящее изображение.
  2. Вы хотите загрузить изображение для плотности вашего устройства, но это изображение будет увеличено или уменьшено. Например, это необходимо, когда вы хотите показать значок запуска большего размера или у вас есть анимация, которая увеличивает размер изображения. В таких случаях, чтобы обеспечить наилучшее качество изображения, вы должны поместить свое изображение в папку mipmap. Что Android сделает, так это попытается взять изображение из корзины с более высокой плотностью, а не масштабировать его.

ТАК

Таким образом, эмпирическое правило, чтобы решить, куда поместить ваше изображение, будет:

  1. Иконки запуска всегда идут в папку mipmap.

  2. Изображения, которые часто масштабируются (или сильно уменьшаются) и качество которых критично для приложения, также попадают в папку mipmap.

  3. Все остальные изображения - обычные рисунки.

Цитата из этой статьи.

Айк Нахапетян
источник
2

При создании отдельных apks для разных плотностей, извлекаемые папки для других плотностей удаляются. Это заставит значки выглядеть размытыми на устройствах, которые используют значки запуска более высокой плотности. Поскольку папки mipmap не удаляются, всегда лучше использовать их для включения значков запуска.

Fartab
источник
1
res/
mipmap-mdpi/ic_launcher.png (48x48 pixels)
mipmap-hdpi/ic_launcher.png (72x72)
mipmap-xhdpi/ic_launcher.png (96x96)
mipmap-xxhdpi/ic_launcher.png (144x144)
mipmap-xxxhdpi/ic_launcher.png (192x192)

MipMap для значка приложения для запуска

http://android-developers.blogspot.co.uk/2014/10/getting-your-apps-ready-for-nexus-6-and.html

https://androidbycode.wordpress.com/2015/02/14/goodbye-launcher-drawables-hello-mipmaps/

Piyush
источник
Спасибо за это второе сообщение в блоге! Это проясняет разницу между использованием drawable-XXXи mipmap-XXXпапками очень хорошо: значок запуска отличается от других ресурсов, так как возможно, что значок с более высоким разрешением отображается в панели запуска пользователей. Если это изображение с более высоким разрешением было извлечено из папки Drawables, то значок с более низкой плотностью будет программно увеличен. Это может вызвать непривлекательный размытый значок.
winklerrr
По крайней мере, в Android 8.1 на Nexus P6 значки запуска в папках drawables НЕ масштабируются. На самом деле не найден вообще, и приложение вылетает при открытии.
Матфея
1

Если вы создаете APK для целевого разрешения экрана, такого как HDPI, инструмент упаковки ресурсов Android, AAPT, может вырезать чертежи для других разрешений, которые вам не нужны. Но если он находится в папке mipmap, то эти ресурсы останутся в APK вне зависимости от целевого разрешения.

Evan
источник
-1

Понимание, которое я имею о mipmap, более или менее похоже на это:

Когда необходимо нарисовать изображение, учитывая, что у нас разные размеры экрана, мы должны принять участие в некотором масштабировании.

Если у вас есть изображение, которое подходит для мобильного телефона низкого уровня, когда вы масштабируете его до размера 10-дюймового планшета, вы должны «изобрести» пиксели, которые на самом деле не существуют. Это делается с помощью некоторого алгоритма интерполяции. Чем больше пикселей нужно изобрести, тем дольше длится процесс, и качество начинает падать. Наилучшее качество достигается с более сложными алгоритмами, которые занимают больше времени (например, среднее число окружающих пикселей по сравнению с копированием ближайшего пикселя).

Чтобы уменьшить количество пикселей, которые нужно изобрести, с помощью mipmap вы предоставляете разные размеры / разрешения одного и того же изображения, и система выберет ближайшее изображение с разрешением, которое должно быть визуализировано, и выполнит масштабирование оттуда. Это должно уменьшить количество изобретенных пикселей, экономя ресурсы, которые будут использоваться при расчете этих пикселей для обеспечения хорошего качества изображения.

Я читал об этом в статье, объясняющей проблему производительности в libgdx при масштабировании изображений:

http://www.badlogicgames.com/wordpress/?p=1403

Juan
источник