Dessin Mipmap pour les icônes

449

Depuis Android 4.3 (Jelly Bean), nous pouvons maintenant utiliser les res/mipmapdossiers pour stocker des images "mipmap".

Par exemple, Chrome pour Android stocke ses icônes dans ces dossiers au lieu des res/drawabledossiers plus normaux .

En quoi ces images mipmap sont-elles différentes des autres images dessinables connues?

Je vois que dans mon manifeste, nous utilisons le @mipmap/qualificatif, au lieu de @drawable/, ce qui est logique étant donné le nom du dossier de ressources:

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

Références:

Le document sur les API d'Android 4.3 dit ce qui suit:

L'utilisation d'une mipmap comme source pour votre bitmap ou dessinable est un moyen simple de fournir une image de qualité et différentes échelles d'image, ce qui peut être particulièrement utile si vous vous attendez à ce que votre image soit mise à l'échelle lors d'une animation.

Android 4.2 (API niveau 17) a ajouté la prise en charge des mipmaps dans la classe Bitmap: Android échange les images mip dans votre Bitmap lorsque vous avez fourni une source mipmap et avez activé setHasMipMap (). Maintenant, dans Android 4.3, vous pouvez également activer les mipmaps pour un objet BitmapDrawable, en fournissant un actif mipmap et en définissant l'attribut android: mipMap dans un fichier de ressources bitmap ou en appelant hasMipMap ().

Je n'y vois rien qui m'aide à comprendre.


Les ressources XML Bitmap ont une android:mipMappropriété:

Booléen. Active ou désactive le conseil mipmap. Voir setHasMipMap () pour plus d'informations. La valeur par défaut est false.

Pour autant que je sache, cela ne s'applique pas aux icônes de lanceur.


La question a été posée sur Google Groupes ( Le but du nom de ressource "mipmap"?! ), Auquel Romain Guy a répondu:

Il est utile de fournir une image à une résolution plus grande qui serait normalement calculée (par exemple, sur un périphérique mdpi, le lanceur peut souhaiter que l'icône hdpi plus grande affiche de grands raccourcis d'application.)

J'ai l'impression que cela a presque du sens, mais pas tout à fait.

Je suis toujours enclin à suivre le suivi de Randy Sugianto:

Quels en sont les avantages? Existe-t-il un guide sur l'utilisation des mipmaps, probablement pour de meilleures icônes de lanceur?


Bien sûr, Wikipedia a une page pour "Mipmap" , qui se réfère à une technique plus ancienne inventée en 1983, que je ne peux pas tout à fait relier à l'implémentation Android actuelle.


Devrions-nous stocker toutes nos icônes d'application dans des res/mipmapdossiers ces jours-ci, et quelles sont les directives pour ces images mipmap?


Mise à jour # 1

Voici un article de blog qui essaie de l'expliquer un peu.

Mais l'image utilisée dans ce billet de blog montre à quoi ressemble un fichier avec de nombreux logos. Ce n'est pas ce que je vois dans le dossier mipmap de Chrome.

Le mipmap-hdpidossier de Chrome contient trois images. L'un est le logo Chrome, à lui seul.

Chrome mipmap-hdpi icon.png

Curieusement, c'est 72x72, pas 48x48 que je m'attendrais à voir.

Peut-être que c'est tout ce qu'il y a à cela - nous avons juste besoin de garder de plus grandes icônes dans les dossiers mipmap?


Mise à jour # 2

Le blog Android Developers Blog du 23/10/2014 confirme à nouveau l'idée d'utiliser les mipmapdossiers pour les icônes d'application:

En parlant de la densité d'écran du Nexus 6, l'auteur écrit:

Il est recommandé de placer les icônes de votre application dans des dossiers mipmap (et non dans les dossiers dessinables) car ils sont utilisés à des résolutions différentes de la densité actuelle de l'appareil. Par exemple, une icône d'application xxxhdpi peut être utilisée sur le lanceur pour un périphérique xxhdpi.


Mise à jour # 3

Notez qu'Android Studio crée les ic_launcher.pngicônes dans les mipmap...dossiers plutôt que les drawable...dossiers qu'Eclipse a utilisés pour les créer.


Richard Le Mesurier
la source

Réponses:

260

Il existe deux utilisations distinctes des mipmaps:

  1. Pour les icônes de lanceur lors de la création de fichiers APK spécifiques à la densité. Certains développeurs créent des fichiers APK distincts pour chaque densité, afin de réduire la taille du fichier APK. Cependant, certains lanceurs (livrés avec certains appareils ou disponibles sur le Play Store) utilisent des tailles d'icônes plus grandes que le 48dp standard. Les lanceurs utilisent getDrawableForDensity et réduisent si nécessaire, plutôt que vers le haut, de sorte que les icônes sont de haute qualité. Par exemple, sur une tablette hdpi, le lanceur peut charger l'icône xhdpi. En plaçant votre icône de lanceur dans le répertoire mipmap-xhdpi, elle ne sera pas supprimée de la même manière qu'un répertoire drawable-xhdpi est lors de la construction d'un APK pour les périphériques hdpi. Si vous créez un seul fichier APK pour tous les appareils, cela n'a pas vraiment d'importance car le lanceur peut accéder aux ressources pouvant être dessinées pour la densité souhaitée.

  2. L'API mipmap réelle de 4.3. Je ne l'ai pas utilisé et je ne le connais pas. Il n'est pas utilisé par les lanceurs Android Open Source Project et je ne connais aucun autre lanceur utilisant.

Kevin TeslaCoil
la source
2
Vous proposez donc un script de construction qui supprime les dossiers de densité incorrects pour tous, sauf les ressources mipmap, si je comprends bien?
Richard Le Mesurier
20
Je suggérerais simplement de créer un APK pour toutes les densités et ne vous inquiétez pas. Mais oui, la raison pour laquelle les répertoires mipmap sont parfois utilisés pour les icônes de lancement est à cause des scripts de construction (aapt - configurations préférées) qui suppriment les répertoires drawable- {densité} mais pas les répertoires mipmap- {densité}. Cela semble presque exploiter un bogue, mais votre citation du post de Romain Guy et Diane Hackborn sur plus.google.com/105051985738280261832/posts/QTA9McYan1L montre que c'est par conception.
Kevin TeslaCoil
3
donc mon processus typique de suppression de mipmap, de placement de mes icônes dans des dessins et de construction d'un seul fichier APK est parfait. Il semble que mipmap soit atypique pour la plupart d'entre nous, mais il est imposé à nous tous.
Someone Somewhere
Dans la documentation, il est dit: "mipmap: fichiers dessinables pour différentes densités d'icônes de lanceur." developer.android.com/guide/topics/resources/…
activité
79

Il semble que Google ait mis à jour ses documents depuis toutes ces réponses, alors j'espère que cela aidera quelqu'un d'autre à l'avenir :) Je suis juste tombé sur cette question moi-même, tout en créant un nouveau (nouveau nouveau) projet.

TL; DR: les drawables peuvent être supprimés dans le cadre de l'optimisation des ressources spécifiques à dp. Les mipmaps ne seront pas supprimés.

Différentes applications de lancement d'écran d'accueil sur différents appareils affichent des icônes de lancement d'application à différentes résolutions. Lorsque les techniques d'optimisation des ressources d'application suppriment des ressources pour les densités d'écran inutilisées, les icônes du lanceur peuvent devenir floues car l'application du lanceur doit mettre à l'échelle une icône de résolution inférieure pour l'affichage. Pour éviter ces problèmes d'affichage, les applications doivent utiliser les mipmap/dossiers de ressources pour les icônes du lanceur. Le système Android préserve ces ressources indépendamment du dépouillement de la densité et garantit que les applications de lancement peuvent choisir des icônes avec la meilleure résolution d'affichage.

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

Kazuaki
la source
2
Cela est cohérent avec l'emplacement par défaut d'Android Studio lors de l'importation d'éléments d'image. Les icônes du lanceur vont dans mipmap; d'autres vont dans drawable.
Edward Brey
2
La documentation semble avoir changé à nouveau, mipmap ne semble pas exister dans developer.android.com/tools/projects/index.html (malgré d'autres morceaux de documentation Android essayant toujours de la référencer).
SomeoneElse
28

En quoi ces images mipmap sont-elles différentes des autres images dessinables connues?

Voici mes deux cents en essayant d'expliquer la différence. Il y a deux cas que vous traitez lorsque vous travaillez avec des images dans Android:

  1. Vous voulez charger une image pour la densité de votre appareil et vous allez l'utiliser "telle quelle", sans changer sa taille réelle . Dans ce cas, vous devez travailler avec des drawables et Android vous donnera la meilleure image.

  2. Vous voulez charger une image pour la densité de votre appareil, mais cette image va être agrandie ou réduite . Par exemple, cela est nécessaire lorsque vous souhaitez afficher une icône de lanceur plus grande ou que vous avez une animation, ce qui augmente la taille de l'image. Dans de tels cas, pour garantir la meilleure qualité d'image, vous devez placer votre image dans le dossier mipmap . Ce que fera Android, c'est qu'il essaiera de récupérer l'image dans un compartiment de densité plus élevée au lieu de la mettre à l'échelle. Cela augmentera la netteté (qualité) de l'image.

Ainsi, la règle de base pour décider où mettre votre image serait:

  • Les icônes du lanceur vont toujours dans le dossier mipmap .
  • Les images, qui sont souvent agrandies (ou extrêmement réduites) et dont la qualité est critique pour l'application, vont également dans le dossier mipmap .
  • Toutes les autres images sont des dessins courants .
sergej shafarenka
la source
Donc, les icônes de la barre d'action ou l'icône du bouton flottant vont dans mipmap?
Juan De la Cruz
Non, ce sont des drawables habituels.
sergej shafarenka
23

L'implémentation Android des mipmaps en 4.3 est exactement la technique de 1983 expliquée dans l'article Wikipedia :)

Chaque image bitmap de l'ensemble mipmap est un double réduit de la texture principale, mais à un certain niveau de détail réduit. Bien que la texture principale soit toujours utilisée lorsque la vue est suffisante pour la rendre en détail, le rendu passera à une image mipmap appropriée (...) lorsque la texture est vue à distance ou à une petite taille.

Bien que cela soit décrit comme une technique pour les graphiques 3D (car il mentionne "la visualisation à distance"), il s'applique tout aussi bien à la 2D (traduit par "dessiné est un espace plus petit", c'est-à-dire "réduit").

Pour un exemple concret Android, imaginez que vous avez une vue avec un certain arrière-plan dessinable (en particulier, a BitmapDrawable). Vous utilisez maintenant une animation pour la mettre à l'échelle à 0,15 de sa taille d'origine. Normalement, cela nécessiterait de réduire l'échelle du bitmap d'arrière-plan pour chaque image. Cette réduction d'échelle «extrême» peut cependant produire des artefacts visuels.

Vous pouvez cependant fournir un mipmap, ce qui signifie que l'image est déjà pré-rendue pour quelques échelles spécifiques (disons 1.0, 0.5 et 0.25). Chaque fois que l'animation "franchit" le seuil de 0,5, au lieu de continuer à réduire l'échelle de l'image de taille 1,0 d'origine, elle passera à l'image de 0,5 et la réduira, ce qui devrait fournir un meilleur résultat. Et ainsi de suite alors que l'animation continue.

C'est un peu théorique, car c'est en fait le rendu. Selon la source de la classe Bitmap, ce n'est qu'un indice, et le rendu peut ou non l'honorer.

/**
 * 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);
}

Je ne sais pas vraiment pourquoi cela conviendrait particulièrement aux icônes d'application. Bien qu'Android sur les tablettes, ainsi que certains lanceurs (par exemple GEL), demandent une icône "une densité plus élevée" pour l'afficher plus grand, cela est censé être fait en utilisant le mécanisme normal (c'est drawable-xxxhdpi-à- dire , & c).

matiash
la source
Cela n'explique pas vraiment la différence avec les drawabledossiers qui contiennent également des images mipmappées.
Timmmm
2
En fait, cette réponse est tout à fait fausse. La seule différence est de savoir si les fichiers sont supprimés ou non - cela n'a rien à voir avec l'utilisation ou non du mipmapping (c'est dans les deux cas). Le dossier est un peu mal nommé; ils auraient probablement dû l'appeler drawable-nostripou quelque chose.
Timmmm
2
Belle explication des mipmaps, mais la réponse de Kazuaki se référant à une entrée de doc Google semble impliquer que ce n'est en fait pas la raison.
Trilarion
11

Une chose que j'ai mentionnée dans un autre fil qui mérite d'être soulignée - si vous construisez différentes versions de votre application pour différentes densités, vous devriez connaître le répertoire de ressources "mipmap". C'est exactement comme les ressources "dessinables", sauf qu'il ne participe pas à la suppression de densité lors de la création des différentes cibles apk.

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

kreker
la source
... oui en effet, comme mentionné par Kevin dans la réponse acceptée. Cela semble avoir été la principale raison derrière cela.
Richard Le Mesurier
@RichardLeMesurier oui, juste pour être bref et clair
kreker
4

Comme je cherchais une réponse clarifiée à cela pour déterminer le bon type d'icônes de notification, je voudrais ajouter cette déclaration claire au sujet. C'est de http://developer.android.com/tools/help/image-asset-studio.html#saving

Remarque: les fichiers d'icônes du lanceur résident dans un emplacement différent de celui des autres icônes. Ils se trouvent dans le dossier mipmap /. Tous les autres fichiers d'icônes résident dans le dossier drawable / de votre projet.

Stev
la source
2

Lors de la construction d'apks séparés pour différentes densités, les dossiers dessinables pour d'autres densités sont supprimés. Cela rendra les icônes floues dans les appareils qui utilisent des icônes de lancement de densité plus élevée. Étant donné que les dossiers mipmap ne sont pas supprimés, il est toujours préférable de les utiliser pour inclure les icônes du lanceur.

Fartab
la source
2

Il y a deux cas que vous traitez lorsque vous travaillez avec des images dans Android:

  1. Vous voulez charger une image pour la densité de votre appareil et vous allez l'utiliser "telle quelle", sans changer sa taille réelle. Dans ce cas, vous devez travailler avec des tirables et Android vous donnera la meilleure image.
  2. Vous souhaitez charger une image pour la densité de votre appareil, mais cette image va être agrandie ou réduite. Par exemple, cela est nécessaire lorsque vous souhaitez afficher une icône de lanceur plus grande ou que vous avez une animation, ce qui augmente la taille de l'image. Dans de tels cas, pour garantir la meilleure qualité d'image, vous devez placer votre image dans le dossier mipmap. Ce que fera Android, c'est qu'il essaiera de récupérer l'image dans un compartiment de densité plus élevée au lieu de la mettre à l'échelle.

DONC

Ainsi, la règle de base pour décider où mettre votre image serait:

  1. Les icônes du lanceur vont toujours dans le dossier mipmap.

  2. Les images, qui sont souvent agrandies (ou extrêmement réduites) et dont la qualité est critique pour l'application, vont également dans le dossier mipmap.

  3. Toutes les autres images sont des dessins courants.

Citation de cet article.

Hayk Nahapetyan
la source
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)

Icône MipMap for app pour lanceur

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
la source
Merci pour ce deuxième article de blog! Cela clarifie très bien la différence entre l'utilisation de drawable-XXXet les mipmap-XXXdossiers: l' icône du lanceur est différente des autres ressources car il est possible qu'une icône de résolution plus élevée soit affichée dans le lanceur des utilisateurs. Si cette image de résolution supérieure a été supprimée de votre dossier de dessin, une icône de densité inférieure sera mise à l'échelle par programme. Cela peut provoquer une icône floue peu attrayante.
winklerrr
Au moins dans Android 8.1 sur Nexus P6, les icônes de lancement dans les dossiers drawables NE SONT PAS agrandies. En fait, pas trouvé du tout et l'application se bloque à l'ouverture.
matthew
1

Si vous créez un fichier APK pour une résolution d'écran cible comme HDPI, l'outil de mise en package des ressources Android, AAPT, peut supprimer les dessinables pour une autre résolution dont vous n'avez pas besoin, mais s'il se trouve dans le dossier mipmap, ces ressources resteront dans le APK, quelle que soit la résolution cible.

Evan
la source
-1

Ma compréhension du mipmap est plus ou moins la suivante:

Lorsqu'une image doit être dessinée, étant donné que différentes tailles d'écran sont des résolutions, une certaine mise à l'échelle devra y participer.

Si vous avez une image qui convient à un téléphone portable bas de gamme, lorsque vous la redimensionnez à la taille d'une tablette de 10 pouces, vous devez "inventer" des pixels qui n'existent pas réellement. Cela se fait avec un algorithme d'interpolation. plus il y a de pixels à inventer, plus le processus prend du temps et la qualité commence à échouer. La meilleure qualité est obtenue avec des algorithmes plus complexes qui prennent plus de temps (moyenne des pixels environnants vs copie du pixel le plus proche par exemple).

Pour réduire le nombre de pixels à inventer, avec mipmap vous fournissez différentes tailles / résolutions de la même image, et le système choisira l'image la plus proche de la résolution qui doit être rendue et effectuera la mise à l'échelle à partir de là. Cela devrait réduire le nombre de pixels inventés économisant des ressources à utiliser dans le calcul de ces pixels pour fournir une image de bonne qualité.

J'ai lu à ce sujet dans un article expliquant un problème de performances dans libgdx lors de la mise à l'échelle des images:

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

Juan
la source