Drawable Mipmap dla ikon

449

Od Androida 4.3 (Jelly Bean) możemy teraz korzystać z res/mipmapfolderów do przechowywania obrazów „mipmap”.

Na przykład Chrome na Androida przechowuje swoje ikony w tych folderach zamiast bardziej normalnych res/drawablefolderów.

Czym różnią się te obrazy mipmap od innych znanych rysowalnych obrazów?

Widzę, że w moim manifeście używamy @mipmap/kwalifikatora zamiast @drawable/, co ma sens, biorąc pod uwagę nazwę folderu zasobów:

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

Bibliografia:

Dokument interfejsu API systemu Android 4.3 ma następujące zdanie:

Użycie mipmapy jako źródła dla mapy bitowej lub rysowalnej jest prostym sposobem na zapewnienie wysokiej jakości obrazu i różnych skal obrazu, co może być szczególnie przydatne, jeśli spodziewasz się skalowania obrazu podczas animacji.

Android 4.2 (API poziom 17) dodał obsługę mipmap w klasie Bitmap - Android zamienia obrazy mip w Bitmapie, gdy podałeś źródło mipmap i włączyłeś setHasMipMap (). Teraz w Androidzie 4.3 możesz włączyć mipmapy również dla obiektu BitmapDrawable, podając zasób mipmap i ustawiając atrybut android: mipMap w pliku zasobów bitmapy lub wywołując hasMipMap ().

Nie widzę tam nic, co pomogłoby mi zrozumieć.


Zasoby bitmapy XML mają android:mipMapwłaściwość:

Boolean. Włącza lub wyłącza wskazówkę mipmap. Aby uzyskać więcej informacji, zobacz setHasMipMap (). Wartość domyślna to false.

O ile mi wiadomo, nie dotyczy to ikon programu uruchamiającego.


Pytanie zostało zadane w Grupach dyskusyjnych Google ( celem nazwy zasobu „mipmap” ?! ), na co odpowiedział Romain Guy:

Przydatne jest dostarczenie obrazu o większej rozdzielczości, który normalnie byłby obliczany (na przykład na urządzeniu mdpi Launcher może chcieć, aby większa ikona hdpi wyświetlała duże skróty do aplikacji).

Wydaje mi się, że to prawie ma sens, ale nie do końca.

Nadal jestem skłonny do śledzenia Randy'ego Sugianto:

Jakie są tego zalety? Czy jest jakiś przewodnik jak używać mipmap, prawdopodobnie dla lepszych ikon programów uruchamiających?


Oczywiście Wikipedia ma stronę „Mipmap” , która odnosi się do starszej techniki wynalezionej w 1983 r., Której nie mogę do końca powiązać z obecną implementacją Androida.


Czy powinniśmy teraz przechowywać wszystkie nasze ikony aplikacji w res/mipmapfolderach i jakie są wytyczne dla tych obrazów mipmap?


Aktualizacja nr 1

Oto post na blogu, który próbuje to trochę wyjaśnić.

Ale obraz użyty w tym blogu pokazuje, jak wygląda jeden plik z wieloma logo. Nie tego widzę w folderze mipmap Chrome.

mipmap-hdpiFolder Chrome zawiera trzy obrazy. Jednym z nich jest samo logo Chrome.

Chrome mipmap-hdpi icon.png

O dziwo, to 72x72, a nie 48x48, których spodziewałbym się zobaczyć.

Być może to wszystko - musimy po prostu przechowywać większe ikony w folderach mipmap?


Aktualizacja nr 2

W blogu deweloperów Androida z 23.10.2014 ponownie potwierdzono pomysł użycia mipmapfolderów na ikony aplikacji:

Mówiąc o gęstości ekranu Nexusa 6, autor pisze:

Najlepszą praktyką jest umieszczanie ikon aplikacji w folderach mipmap (nie folderach rysowalnych), ponieważ są one używane w rozdzielczościach innych niż aktualna gęstość urządzenia. Na przykład ikona aplikacji xxxhdpi może być używana w programie uruchamiającym dla urządzenia xxhdpi.


Aktualizacja nr 3

Pamiętaj, że Android Studio tworzy ic_launcher.pngikony w mipmap...folderach, a nie w drawable...folderach, w których Eclipse je utworzył.


Richard Le Mesurier
źródło

Odpowiedzi:

260

Istnieją dwa różne zastosowania mipmap:

  1. Dla ikon programu uruchamiającego podczas budowania APK specyficznych dla gęstości. Niektórzy programiści budują osobne pliki APK dla każdej gęstości, aby zmniejszyć rozmiar pliku APK. Jednak niektóre wyrzutnie (dostarczane z niektórymi urządzeniami lub dostępne w Sklepie Play) używają większych rozmiarów ikon niż standardowe 48dp. Wyrzutnie używają getDrawableForDensity i zmniejszają w razie potrzeby zamiast w górę, więc ikony są wysokiej jakości. Na przykład na tablecie hdpi program uruchamiający może załadować ikonę xhdpi. Umieszczając ikonę programu uruchamiającego w katalogu mipmap-xhdpi, nie zostanie ona usunięta tak, jak katalog rysowany-xhdpi podczas budowania pakietu APK dla urządzeń hdpi. Jeśli budujesz pojedynczy pakiet APK dla wszystkich urządzeń, nie ma to tak naprawdę znaczenia, ponieważ program uruchamiający może uzyskać dostęp do zasobów, które można pobrać, dla żądanej gęstości.

  2. Rzeczywisty interfejs API mipmap z 4.3. Nie korzystałem z tego i nie jestem z tym zaznajomiony. Nie jest używany przez programy uruchamiające Android Open Source Project i nie znam innych programów uruchamiających.

Kevin TeslaCoil
źródło
2
Sugerujesz więc skrypt kompilacji, który usuwa niepoprawne foldery gęstości dla wszystkich zasobów oprócz mipmap, jeśli dobrze rozumiem?
Richard Le Mesurier
20
Sugeruję zbudowanie jednego APK dla wszystkich gęstości i nie martw się o to. Ale tak, powodem, dla którego katalogi mipmap są czasami używane w ikonach programu uruchamiającego, są skrypty kompilacji (aapt - preferowane konfiguracje) usuwające katalogi rysowalne {gęstość}, ale nie katalogi mipmap- {gęstość}. Wygląda na to, że wykorzystuje się błąd, ale cytat z postu Romaina Guy'a i Diane Hackborn na plus.google.com/105051985738280261832/posts/QTA9McYan1L pokazuje, że jest to projekt.
Kevin TeslaCoil
3
więc mój typowy proces usuwania mipmapy, umieszczania ikon w rysunkach i budowania pojedynczego pliku APK jest idealny. Wygląda na to, że mipmap jest nietypowy dla większości z nas deweloperów, ale jest wymuszony na nas wszystkich.
Ktoś gdzieś
W dokumentacji napisano: „mipmap: pliki do rysowania dla różnych gęstości ikon programu uruchamiającego”. developer.android.com/guide/topics/resources/…
aktywność
79

Wygląda na to, że Google zaktualizowało swoje dokumenty od wszystkich tych odpowiedzi, więc mam nadzieję, że pomoże to komuś innemu :) Właśnie natrafiłem na to pytanie podczas tworzenia nowego (nowego) projektu.

TL; DR: drawable mogą być usuwane w ramach optymalizacji zasobów specyficznej dla dp. Mipmapy nie zostaną usunięte.

Różne aplikacje uruchamiające ekran główny na różnych urządzeniach wyświetlają ikony uruchamiania aplikacji w różnych rozdzielczościach. Gdy techniki optymalizacji zasobów aplikacji usuwają zasoby dla nieużywanych gęstości ekranu, ikony programu uruchamiającego mogą wyglądać na rozmyte, ponieważ aplikacja uruchamiająca musi przeskalować ikonę o niższej rozdzielczości do wyświetlenia. Aby uniknąć tych problemów z wyświetlaniem, aplikacje powinny używać mipmap/folderów zasobów dla ikon programu uruchamiającego. System Android zachowuje te zasoby bez względu na usuwanie gęstości i zapewnia, że ​​aplikacje uruchamiające mogą wybierać ikony o najlepszej rozdzielczości do wyświetlenia.

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

Kazuaki
źródło
2
Jest to zgodne z domyślnym umiejscowieniem Android Studio podczas importowania zasobów obrazu. Ikony uruchamiania przechodzą w mipmap; inni przechodzą do ciągnienia.
Edward Brey,
2
Wydaje się, że dokumentacja znów się zmieniła, mipmap wydaje się nie istnieć w developer.android.com/tools/projects/index.html (pomimo innych fragmentów dokumentacji Androida wciąż próbujących się do niej odwoływać).
SomeoneElse
28

Czym różnią się te obrazy mipmap od innych znanych rysowalnych obrazów?

Oto moje dwa centy za próbę wyjaśnienia różnicy. Podczas pracy z obrazami w Androidzie masz do czynienia z dwoma przypadkami:

  1. Chcesz załadować obraz dla swojej gęstości urządzenia i będziesz go używać „tak jak jest”, bez zmiany jego rzeczywistego rozmiaru . W takim przypadku powinieneś pracować z rysunkami, a Android zapewni ci najlepiej pasujący obraz.

  2. Chcesz załadować obraz dla swojej gęstości urządzenia, ale obraz ten zostanie przeskalowany w górę lub w dół . Jest to na przykład potrzebne, gdy chcesz wyświetlić większą ikonę programu uruchamiającego lub masz animację, która zwiększa rozmiar obrazu. W takich przypadkach, aby zapewnić najlepszą jakość obrazu, należy umieścić obraz w folderze mipmap . Android będzie próbował odebrać obraz z wiadra o wyższej gęstości zamiast go skalować. Zwiększy to ostrość (jakość) obrazu.

Zatem ogólna zasada decydująca o tym, gdzie umieścić obraz, to:

  • Ikony programu uruchamiającego zawsze przechodzą do folderu mipmap .
  • Obrazy, które są często skalowane (lub bardzo skalowane) i których jakość jest krytyczna dla aplikacji, również trafiają do folderu mipmap .
  • Wszystkie pozostałe obrazy są zwykłymi rysunkami .
sergej shafarenka
źródło
Więc ikony paska akcji lub ikona pływającego przycisku są w mipmapie?
Juan De la Cruz
Nie, są one zwykle dostępne.
sergej shafarenka
23

Implementacja mipmap na Androida w 4.3 jest dokładnie techniką z 1983 roku wyjaśnioną w artykule na Wikipedii :)

Każdy obraz bitmapowy zestawu mipmap jest pomniejszonym duplikatem głównej tekstury, ale z pewnym zmniejszonym poziomem szczegółowości. Chociaż główna tekstura byłaby nadal używana, gdy widok jest wystarczający do renderowania jej w pełni szczegółów, renderer przełączy się na odpowiedni obraz mipmap (...), gdy tekstura jest oglądana z daleka lub w małym rozmiarze.

Chociaż jest to opisywane jako technika grafiki 3D (ponieważ wspomina o „oglądaniu z dystansu”), to samo dotyczy również 2D (przetłumaczone jako „narysowana jest mniejsza przestrzeń”, tj. „Przeskalowana w dół”).

Na konkretny przykład Androida wyobraź sobie, że masz Widok z określonym tłem do rysowania (w szczególności a BitmapDrawable). Teraz używasz animacji, aby przeskalować ją do 0,15 oryginalnego rozmiaru. Zwykle wymagałoby to zmniejszenia skali bitmapy tła dla każdej klatki. To „ekstremalne” zmniejszanie skali może jednak powodować powstawanie artefaktów wizualnych.

Możesz jednak podać mipmapę, co oznacza, że ​​obraz jest już wstępnie renderowany dla kilku określonych skal (powiedzmy 1,0, 0,5 i 0,25). Ilekroć animacja „przekroczy” próg 0,5, zamiast kontynuować zmniejszanie oryginalnego obrazu o rozmiarze 1,0, przełącza się na obraz 0,5 i przeskalowuje go w dół, co powinno zapewnić lepszy wynik. I tak dalej, gdy animacja trwa.

Jest to trochę teoretyczne, ponieważ faktycznie robi to renderer. Według źródła klasy Bitmap jest to tylko podpowiedź, a mechanizm renderujący może ją honorować lub nie.

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

Nie jestem jednak do końca pewien, dlaczego byłoby to szczególnie odpowiednie w przypadku ikon aplikacji. Chociaż Android na tabletach, a także niektóre wyrzutnie (np. GEL), żądają ikony „o większej gęstości”, aby pokazać ją większą, należy to zrobić przy użyciu zwykłego mechanizmu (tj. drawable-xxxhdpi& C).

matiash
źródło
To tak naprawdę nie wyjaśnia różnicy w stosunku do drawablefolderów, które również zawierają obrazy zmapowane.
Timmmm,
2
W rzeczywistości ta odpowiedź jest po prostu błędna. Tylko różnicą jest to, czy pliki są usuwane lub nie - to nie ma nic wspólnego z tym, czy też nie mipmappingu jest używany (jest to w obu przypadkach). Folder jest źle nazwany; prawdopodobnie powinni tak to nazwać drawable-nostrip.
Timmmm,
2
Ładne wyjaśnienie mipmap, ale odpowiedź Kazuaki odnosząca się do wpisu w dokumencie Google wydaje się sugerować, że tak naprawdę nie jest to powód.
Trilarion
11

Warto wspomnieć o jednej rzeczy w innym wątku - jeśli budujesz różne wersje aplikacji dla różnych gęstości, powinieneś wiedzieć o katalogu zasobów „mipmap”. To jest dokładnie tak, jak „wyciągalne” zasoby, z tym wyjątkiem, że nie bierze udziału w usuwaniu gęstości podczas tworzenia różnych celów apk.

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

kreker
źródło
... tak, jak wspomniał Kevin w przyjętej odpowiedzi. Wydaje się, że był to główny powód.
Richard Le Mesurier,
@RichardLeMesurier tak, żeby było krótko i jasno
kreker
4

Ponieważ szukałem odpowiedzi na to pytanie, aby określić odpowiedni typ ikon powiadomień, chciałbym dodać to jasne stwierdzenie do tematu. Pochodzi z http://developer.android.com/tools/help/image-asset-studio.html#saving

Uwaga: pliki ikon programu uruchamiającego znajdują się w innym miejscu niż inne ikony. Znajdują się one w folderze mipmap /. Wszystkie inne pliki ikon znajdują się w folderze / projekcie twojego projektu.

Stev
źródło
2

Podczas budowania oddzielnych aplikacji dla różnych gęstości, usuwalne foldery dla innych gęstości są usuwane. Sprawi to, że ikony będą rozmazane na urządzeniach, które używają ikon uruchamiania o większej gęstości. Ponieważ foldery mipmap nie są usuwane, zawsze najlepiej jest używać ich do dołączania ikon programu uruchamiającego.

Fartab
źródło
2

Podczas pracy z obrazami w Androidzie masz do czynienia z dwoma przypadkami:

  1. Chcesz załadować obraz dla swojej gęstości urządzenia i będziesz go używać „tak jak jest”, bez zmiany jego rzeczywistego rozmiaru. W takim przypadku powinieneś pracować z rysunkami, a Android zapewni ci najlepiej pasujący obraz.
  2. Chcesz załadować obraz dla swojej gęstości urządzenia, ale obraz ten zostanie przeskalowany w górę lub w dół. Jest to na przykład potrzebne, gdy chcesz wyświetlić większą ikonę programu uruchamiającego lub masz animację, która zwiększa rozmiar obrazu. W takich przypadkach, aby zapewnić najlepszą jakość obrazu, należy umieścić obraz w folderze mipmap. Android będzie próbował odebrać obraz z wiadra o wyższej gęstości zamiast go skalować.

WIĘC

Zatem ogólna zasada decydująca o tym, gdzie umieścić obraz, to:

  1. Ikony programu uruchamiającego zawsze przechodzą do folderu mipmap.

  2. Obrazy, które są często skalowane (lub bardzo skalowane) i których jakość jest krytyczna dla aplikacji, również trafiają do folderu mipmap.

  3. Wszystkie pozostałe obrazy są zwykłymi rysunkami.

Cytat z tego artykułu.

Hayk Nahapetyan
źródło
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 dla ikony aplikacji dla programu uruchamiającego

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
źródło
Dziękuję za ten drugi post na blogu! Naprawdę dobrze wyjaśnia różnicę między użyciem drawable-XXXi mipmap-XXXfolderami: Ikona programu uruchamiającego różni się od innych zasobów, ponieważ możliwe jest, że w programie uruchamiającym użytkowników wyświetlana jest ikona wyższej rozdzielczości. Jeśli obraz o wyższej rozdzielczości został usunięty z folderu drawables, ikona o niższej gęstości zostanie programowo powiększona. Może to powodować nieatrakcyjną rozmytą ikonę.
winklerrr
Przynajmniej w Androidzie 8.1 na Nexusie P6 ikony uruchamiania w folderach drawable NIE są skalowane. Właściwie wcale nie znaleziono, a aplikacja zawiesza się podczas otwierania.
Matthew
1

Jeśli zbudujesz pakiet APK dla docelowej rozdzielczości ekranu, takiej jak HDPI, narzędzie do pakietowania zasobów dla systemu Android, AAPT, może usunąć pliki do rysowania w celu uzyskania innej rozdzielczości, której nie potrzebujesz, ale jeśli znajduje się w folderze mipmap, wówczas te zasoby pozostaną w APK, niezależnie od rozdzielczości docelowej.

Evan
źródło
-1

Rozumienie, jakie mam na temat mipmap, jest mniej więcej takie:

Kiedy obraz musi zostać narysowany, biorąc pod uwagę, że mamy różne rozmiary ekranów, są rozdzielczości, trzeba będzie wziąć udział w skalowaniu.

Jeśli masz obraz, który jest odpowiedni dla niższej klasy telefonu komórkowego, po skalowaniu go do rozmiaru 10-calowego tabletu musisz „wymyślić” piksele, które w rzeczywistości nie istnieją. Jest to realizowane za pomocą pewnego algorytmu interpolacji. im więcej pikseli trzeba wymyślić, tym dłużej trwa proces, a jakość zaczyna się nie powieść. Najlepszą jakość uzyskuje się przy bardziej złożonych algorytmach, które trwają dłużej (na przykład średnia pikseli otaczających w porównaniu do skopiowania najbliższego piksela).

Aby zmniejszyć liczbę pikseli, które muszą zostać wynalezione, za pomocą mipmapy podajesz różne rozmiary / rozdzielczości tego samego obrazu, a system wybierze obraz najbliższy rozdzielczości, która ma zostać wyrenderowana i dokona skalowania od tego miejsca. Powinno to zmniejszyć liczbę wymyślonych pikseli oszczędzających zasoby, które zostaną wykorzystane do obliczenia tych pikseli, aby zapewnić obraz dobrej jakości.

Przeczytałem o tym w artykule wyjaśniającym problem z wydajnością w libgdx podczas skalowania obrazów:

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

Juan
źródło