Mipmap drawables para ícones

449

Desde o Android 4.3 (Jelly Bean), agora podemos fazer uso das res/mipmappastas para armazenar imagens "mipmap".

Por exemplo, o Chrome para Android armazena seus ícones nessas pastas em vez das res/drawablepastas mais normais .

Como essas imagens mipmap são diferentes das outras imagens desenháveis ​​familiares?

Vejo que, no meu manifesto, usamos o @mipmap/qualificador, em vez de @drawable/, o que faz sentido, considerando o nome da pasta do recurso:

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

Referências:

O documento APIs do Android 4.3 tem o seguinte a dizer:

Usar um mipmap como fonte para seu bitmap ou desenho é uma maneira simples de fornecer uma imagem de qualidade e várias escalas de imagem, o que pode ser particularmente útil se você espera que sua imagem seja dimensionada durante uma animação.

O Android 4.2 (API nível 17) adicionou suporte para mipmaps na classe Bitmap - o Android troca as imagens mip no seu Bitmap quando você fornece uma fonte de mipmap e ativou setHasMipMap (). Agora no Android 4.3, você também pode ativar os mipmaps para um objeto BitmapDrawable, fornecendo um ativo mipmap e definindo o atributo android: mipMap em um arquivo de recurso de bitmap ou chamando hasMipMap ().

Não vejo nada lá que me ajude a entender.


Os recursos de bitmap XML têm uma android:mipMappropriedade:

Boleano. Ativa ou desativa a dica do mipmap. Veja setHasMipMap () para mais informações. O valor padrão é falso.

Isso não se aplica aos ícones do iniciador, tanto quanto eu posso ver.


A questão foi levantada nos Grupos do Google ( O objetivo do nome do recurso "mipmap" ?! ), ao qual Romain Guy respondeu:

É útil fornecer uma imagem em uma resolução maior que normalmente seria computada (por exemplo, em um dispositivo mdpi, o Launcher pode querer que o ícone maior do hdpi exiba atalhos de aplicativos grandes.)

Eu sinto que isso quase faz sentido, mas não completamente.

Ainda estou inclinado a acompanhar o acompanhamento de Randy Sugianto:

Quais são as vantagens disso? Existe algum guia sobre como usar mipmaps, provavelmente para melhores ícones do iniciador?


Obviamente, a Wikipedia possui uma página para o "Mipmap" , que se refere a uma técnica mais antiga inventada em 1983, que não consigo relacionar com a implementação atual do Android.


Atualmente, devemos armazenar todos os ícones de aplicativos em res/mipmappastas e quais são as diretrizes para essas imagens mipmap?


Atualização # 1

Aqui está uma postagem no blog que tenta explicar um pouco.

Mas a imagem usada nessa postagem do blog mostra o que parece um arquivo com muitos logotipos. Não é isso que vejo na pasta mipmap do Chrome.

A mipmap-hdpipasta do Chrome contém três imagens. Um é o logotipo do Chrome, por si só.

Chrome mipmap-hdpi icon.png

Estranhamente, é 72x72, não 48x48, que eu esperaria ver.

Talvez isso seja tudo o que há para isso - precisamos apenas manter ícones maiores nas pastas mipmap?


Atualização # 2

A postagem do blog de desenvolvedores do Android de 23/10/2014 confirma novamente a ideia de usar as mipmappastas para os ícones de aplicativos:

Ao falar sobre a densidade da tela do Nexus 6, o autor escreve:

É uma prática recomendada colocar os ícones do seu aplicativo em pastas mipmap (não nas pastas desenháveis), pois elas são usadas em resoluções diferentes da densidade atual do dispositivo. Por exemplo, um ícone de aplicativo xxxhdpi pode ser usado no iniciador para um dispositivo xxhdpi.


Atualização # 3

Observe que o Android Studio cria os ic_launcher.pngícones nas mipmap...pastas, e não nas drawable...pastas que o Eclipse usou para criá-los.


Richard Le Mesurier
fonte

Respostas:

260

Existem dois usos distintos de mipmaps:

  1. Para ícones do iniciador ao criar APKs específicos de densidade. Alguns desenvolvedores criam APKs separados para cada densidade, para manter o tamanho do APK baixo. No entanto, alguns lançadores (fornecidos com alguns dispositivos ou disponíveis na Play Store) usam tamanhos de ícone maiores que o padrão de 48dp. Os lançadores usam getDrawableForDensity e diminuem a escala, se necessário, e não para cima, para que os ícones sejam de alta qualidade. Por exemplo, em um tablet hdpi, o iniciador pode carregar o ícone xhdpi. Ao colocar o ícone do iniciador no diretório mipmap-xhdpi, ele não será removido da maneira que um diretório drawable-xhdpi é ao criar um APK para dispositivos hdpi. Se você estiver criando um único APK para todos os dispositivos, isso realmente não importa, pois o iniciador pode acessar os recursos desenháveis ​​para a densidade desejada.

  2. A API atual do mipmap de 4.3. Eu não usei isso e não estou familiarizado com isso. Ele não é usado pelos lançadores do Android Open Source Project e não conheço nenhum outro lançador usando.

Kevin TeslaCoil
fonte
2
Então, você está sugerindo um script de construção que retira as pastas de densidade incorretas para todos, exceto os recursos do mipmap, se bem entendi?
Richard Le Mesurier
20
Sugiro apenas criar um APK para todas as densidades e não se preocupar com isso. Mas sim, o motivo pelo qual os diretórios mipmap às vezes são usados ​​para ícones do iniciador é por causa dos scripts de construção (aapt --preferred-settings) eliminando os diretórios drawable- {density}, mas não os diretórios mipmap- {density}. Parece quase como explorar um bug, mas sua citação da postagem de Romain Guy e Diane Hackborn em plus.google.com/105051985738280261832/posts/QTA9McYan1L mostra que é por design.
precisa
3
portanto, meu processo típico de excluir o mipmap, colocar meus ícones em desenháveis ​​e criar um único APK é perfeito. Parece que o mipmap é atípico para a maioria de nós desenvolvedores, mas é forçado a todos nós.
Alguém em algum lugar
Na documentação, diz: "mipmap: arquivos desenháveis ​​para diferentes densidades de ícones do iniciador". developer.android.com/guide/topics/resources/…
activity
79

Parece que o Google atualizou seus documentos desde todas essas respostas, então espero que isso ajude outra pessoa no futuro :) Acabei de me deparar com essa pergunta enquanto criava um novo (novo) novo projeto.

TL; DR: os drawables podem ser removidos como parte da otimização de recursos específicos do dp. Os mipmaps não serão removidos.

Diferentes aplicativos do iniciador de tela inicial em dispositivos diferentes mostram ícones do iniciador de aplicativos em várias resoluções. Quando as técnicas de otimização de recursos do aplicativo removem recursos para densidades de tela não utilizadas, os ícones do iniciador podem ficar com uma aparência imprecisa porque o aplicativo iniciador precisa aprimorar um ícone de resolução mais baixa para exibição. Para evitar esses problemas de exibição, os aplicativos devem usar as mipmap/pastas de recursos para os ícones do iniciador. O sistema Android preserva esses recursos, independentemente da redução de densidade, e garante que os aplicativos do iniciador possam escolher ícones com a melhor resolução para exibição.

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

Kazuaki
fonte
2
Isso é consistente com o canal padrão do Android Studio ao importar ativos de imagem. Os ícones do iniciador entram no mipmap; outros entram no drawable.
Edward Brey
2
A documentação parece ter mudado novamente, o mipmap parece não existir no developer.android.com/tools/projects/index.html (apesar de outros bits da documentação do Android ainda tentarem referenciá-la).
someoneelse
28

Como essas imagens mipmap são diferentes das outras imagens desenháveis ​​familiares?

Aqui estão meus dois centavos na tentativa de explicar a diferença. Há dois casos com os quais você lida ao trabalhar com imagens no Android:

  1. Você deseja carregar uma imagem para a densidade do seu dispositivo e usá-la "como está", sem alterar o tamanho real . Nesse caso, você deve trabalhar com desenháveis e o Android fornecerá a imagem mais adequada.

  2. Você deseja carregar uma imagem para a densidade do seu dispositivo, mas essa imagem será ampliada ou reduzida . Por exemplo, isso é necessário quando você deseja mostrar um ícone maior do iniciador ou se tem uma animação que aumenta o tamanho da imagem. Nesses casos, para garantir a melhor qualidade de imagem, você deve colocar sua imagem na pasta mipmap . O que o Android fará é tentar capturar a imagem de um balde de maior densidade em vez de aumentá-la. Isso aumentará a nitidez (qualidade) da imagem.

Assim, a regra geral para decidir onde colocar sua imagem seria:

  • Os ícones do iniciador sempre entram na pasta mipmap .
  • As imagens, que geralmente são ampliadas (ou extremamente reduzidas) e cuja qualidade é crítica para o aplicativo, também são exibidas na pasta mipmap .
  • Todas as outras imagens são desenhadas normalmente .
sergej shafarenka
fonte
Então, os ícones da barra de ação ou o ícone do botão flutuante aparecem no mipmap?
Juan De la Cruz
Não, são desenháveis ​​de sempre.
sergej Shafarenka
23

A implementação Android dos mipmaps na versão 4.3 é exatamente a técnica de 1983 explicada no artigo da Wikipedia :)

Cada imagem de bitmap do conjunto de mipmap é uma duplicata reduzida da textura principal, mas com um certo nível reduzido de detalhes. Embora a textura principal ainda seja usada quando a vista é suficiente para renderizá-la em detalhes, o renderizador alternará para uma imagem mipmap adequada (...) quando a textura for vista à distância ou em um tamanho pequeno.

Embora isso seja descrito como uma técnica para gráficos 3D (como menciona "visualização à distância"), também se aplica ao 2D (traduzido como "desenhado é um espaço menor", ou seja, "redimensionado").

Para um exemplo concreto do Android, imagine que você tenha uma View com um determinado background desenhável (em particular, a BitmapDrawable). Agora você usa uma animação para dimensioná-la para 0,15 do tamanho original. Normalmente, isso exigiria a redução do tamanho do bitmap de segundo plano para cada quadro. Essa redução "extrema", no entanto, pode produzir artefatos visuais.

Você pode, no entanto, fornecer um mapa mip, o que significa que a imagem já está pré-renderizada para algumas escalas específicas (digamos 1.0, 0.5 e 0.25). Sempre que a animação "ultrapassar" o limite de 0,5, em vez de continuar diminuindo a escala da imagem original de tamanho 1,0, ela será alterada para a imagem 0,5 e diminuída, o que deverá fornecer um resultado melhor. E assim por diante enquanto a animação continua.

Isso é um pouco teórico, pois é realmente feito pelo renderizador. De acordo com a fonte da classe Bitmap, é apenas uma dica, e o renderizador pode ou não respeitá-la.

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

Não sei ao certo por que isso seria especialmente adequado para ícones de aplicativos. Embora o Android em tablets, assim como alguns lançadores (por exemplo, GEL), solicite um ícone "uma densidade mais alta" para mostrá-lo maior, isso deve ser feito usando o mecanismo regular (ou seja drawable-xxxhdpi, etc.).

matiash
fonte
Isso realmente não explica a diferença das drawablepastas que também contêm imagens mipmap.
Timmm
2
De fato, esta resposta está completamente errada. A única diferença é se os arquivos são removidos ou não - isso não tem nada a ver com o uso ou não do mipmapping (em ambos os casos). A pasta é meio que mal nomeada; eles provavelmente deveriam ter chamado drawable-nostripou algo assim.
Timmm
2
Boa explicação dos mipmaps, mas a resposta de Kazuaki referente a uma entrada de documento do Google parece sugerir que não é esse o motivo.
precisa saber é o seguinte
11

Uma coisa que mencionei em outro segmento que vale a pena ressaltar - se você estiver criando versões diferentes do seu aplicativo para densidades diferentes, deve saber sobre o diretório de recursos "mipmap". É exatamente como os recursos "desenháveis", exceto que ele não participa da redução de densidade ao criar os diferentes destinos de apk.

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

kreker
fonte
... sim, como mencionado por Kevin na resposta aceita. Esta parece ter sido a principal razão por trás disso.
Richard Le Mesurier
@RichardLeMesurier sim, apenas para torná-lo curto e claro
kreker
4

Como estava procurando uma resposta esclarecedora para determinar o tipo certo de ícones de notificação, gostaria de adicionar esta declaração clara ao tópico. É de http://developer.android.com/tools/help/image-asset-studio.html#saving

Nota: Os arquivos do ícone do iniciador residem em um local diferente do de outros ícones. Eles estão localizados na pasta mipmap /. Todos os outros arquivos de ícone residem na pasta drawable / do seu projeto.

Stev
fonte
2

Ao criar apks separados para diferentes densidades, as pastas desenháveis ​​para outras densidades são removidas. Isso fará com que os ícones pareçam embaçados em dispositivos que usam ícones do iniciador de maior densidade. Como as pastas mipmap não são removidas, é sempre melhor usá-las para incluir os ícones do iniciador.

Fartab
fonte
2

Há dois casos com os quais você lida ao trabalhar com imagens no Android:

  1. Você deseja carregar uma imagem para a densidade do seu dispositivo e usá-la "como está", sem alterar seu tamanho real. Nesse caso, você deve trabalhar com desenháveis ​​e o Android fornecerá a imagem mais adequada.
  2. Você deseja carregar uma imagem para a densidade do seu dispositivo, mas essa imagem será ampliada ou reduzida. Por exemplo, isso é necessário quando você deseja mostrar um ícone maior do iniciador ou se tem uma animação que aumenta o tamanho da imagem. Nesses casos, para garantir a melhor qualidade de imagem, você deve colocar sua imagem na pasta mipmap. O que o Android fará é tentar capturar a imagem de um balde de maior densidade em vez de aumentá-la.

TÃO

Assim, a regra geral para decidir onde colocar sua imagem seria:

  1. Os ícones do iniciador sempre entram na pasta mipmap.

  2. As imagens, que geralmente são ampliadas (ou extremamente reduzidas) e cuja qualidade é crítica para o aplicativo, também são exibidas na pasta mipmap.

  3. Todas as outras imagens são desenhadas normalmente.

Citação deste artigo.

Hayk Nahapetyan
fonte
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 para ícone do aplicativo para iniciador

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
fonte
Obrigado pelo segundo post do blog! Ele esclarece muito bem a diferença entre o uso de drawable-XXXe as mipmap-XXXpastas: O ícone do iniciador é diferente de outros recursos, pois é possível que um ícone de maior resolução seja exibido no iniciador de usuários. Se essa imagem de resolução mais alta tiver sido removida da pasta de desenhos, um ícone de densidade mais baixa será programaticamente ampliado. Isso pode causar um ícone embaçado e pouco atraente.
precisa saber é o seguinte
Pelo menos no Android 8.1 no Nexus P6, os ícones de inicialização nas pastas drawables NÃO SÃO redimensionados. Na verdade, não foi encontrado e o aplicativo trava na abertura.
matthew
1

Se você criar um APK para uma resolução de tela de destino, como o HDPI, a ferramenta de empacotamento de recursos do Android, AAPT, poderá remover os drawables de outras resoluções que você não precisa. APK, independentemente da resolução de destino.

Evan
fonte
-1

O entendimento que tenho sobre o mipmap é mais ou menos assim:

Quando uma imagem precisa ser desenhada, uma vez que temos diferentes tamanhos de tela e resoluções, algumas reduções terão que participar.

Se você tem uma imagem aceitável para um telefone celular de ponta, quando a dimensiona para o tamanho de um tablet de 10 ", é necessário" inventar "pixels que realmente não existem. Isso é feito com algum algoritmo de interpolação. quanto mais pixels tiver que ser inventado, mais tempo o processo leva e a qualidade começa a falhar.A melhor qualidade é obtida com algoritmos mais complexos que demoram mais tempo (média de pixels adjacentes versus copiar o pixel mais próximo, por exemplo).

Para reduzir o número de pixels que precisam ser inventados, com o mipmap você fornece diferentes tamanhos / resoluções da mesma imagem, e o sistema escolherá a imagem mais próxima da resolução que deve ser renderizada e fará o dimensionamento a partir daí. Isso deve reduzir o número de pixels inventados, economizando recursos a serem usados ​​no cálculo desses pixels para fornecer uma imagem de boa qualidade.

Eu li sobre isso em um artigo explicando um problema de desempenho no libgdx ao dimensionar imagens:

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

Juan
fonte