Mipmap drawables图标

Ric*_*ier 438 android mipmaps android-drawable

从Android 4.3(Jelly Bean)开始,我们现在可以利用这些res/mipmap文件夹来存储"mipmap"图像.

例如,Chrome for Android将其图标存储在这些文件夹中,而不是更常用的res/drawable文件夹中.

这些mipmap图像与其他熟悉的可绘制图像有何不同?

我看到在我的清单中,我们使用@mipmap/限定符,而不是@drawable/,这对于资源文件夹名称是有意义的:

<activity
    android:name=".MipmapDemp"
    android:icon="@mipmap/ic_launcher" />
Run Code Online (Sandbox Code Playgroud)

参考文献:

Android 4.3的API的文档具有下面要说:

使用mipmap作为位图或drawable的源是提供高质量图像和各种图像比例的简单方法,如果您希望在动画期间缩放图像,这可能特别有用.

Android 4.2(API级别17)在Bitmap类中添加了对mipmap的支持 - 当您提供了mipmap源并启用了setHasMipMap()时,Android会在您的Bitmap中交换mip图像.现在在Android 4.3中,您还可以通过提供mipmap资源并在位图资源文件中设置android:mipMap属性或通过调用hasMipMap()来为BitmapDrawable对象启用mipmaps.

我没有看到任何有助于我理解的东西.


XML Bitmap资源具有以下android:mipMap属性:

布尔.启用或禁用mipmap提示.有关更多信息,请参见setHasMipMap().默认值为false.

就我所见,这不适用于启动器图标.


问题出现在Google网上论坛(资源名称"mipmap"的目的?!)上,Romain Guy回复道:

提供通常可以计算的更大分辨率的图像很有用(例如,在mdpi设备上,Launcher可能希望更大的hdpi图标显示大型应用程序快捷方式.)

我觉得这几乎是有意义的,但并不完全.

我仍然倾向于选择Randy Sugianto的跟进:

这有什么好处?是否有任何指南如何使用mipmap,可能是为了更好的启动器图标?


当然,维基百科有一个"Mipmap"页面,它指的是一种1983年发明的旧技术,我无法与当前的Android实现相关联.


我们现在应该将所有应用程序图标res/mipmap存储文件夹中吗?这些mipmap图像的准则是什么?


更新#1

这是一篇博文,试图解释一下.

但是该博客文章中使用的图像显示了一个包含许多徽标的文件.这不是我在Chrome的mipmap文件夹中看到的.

Chrome的mipmap-hdpi文件夹包含三张图片.一个是Chrome徽标,单独使用.

Chrome mipmap-hdpi icon.png

奇怪的是,它是72x72,而不是48x48,我希望看到.

也许这就是全部 - 我们只需要在mipmap文件夹中保留更大的图标?


更新#2

2014年10月23日的Android开发者博客文章再次证实了将mipmap文件夹用于应用程序图标的想法:

在谈到Nexus 6屏幕密度时,作者写道:

最好将应用程序图标放在mipmap文件夹(而不是drawable文件夹)中,因为它们的分辨率与设备的当前密度不同.例如,可以在启动器上为xxhdpi设备使用xxxhdpi应用程序图标.


更新#3

请注意,Android Studio会ic_launcher.pngmipmap...文件夹中创建图标,而不是drawable...Eclipse用于创建文件夹的文件夹.


Kev*_*oil 256

mipmap有两种不同的用途:

  1. 用于构建密度特定APK时的启动器图标.一些开发人员为每个密度构建单独的APK,以保持APK大小.但是,某些发射器(随某些设备一起提供,或在Play商店中提供)使用比标准48dp更大的图标尺寸.启动器使用getDrawableForDensity并在需要时缩小,而不是向上,因此图标质量很高.例如,在hdpi平板电脑上,启动器可能会加载xhdpi图标.通过将启动器图标放在mipmap-xhdpi目录中,在为hdpi设备构建APK时,它不会像drawable-xhdpi目录那样被剥离.如果您正在为所有设备构建单个APK,那么这并不重要,因为启动程序可以访问可绘制资源以获得所需的密度.

  2. 4.3的实际mipmap API.我没有使用它,我不熟悉它.它没有被Android开源项目启动器使用,我也不知道有任何其他启动器使用.

  • 我建议只为所有密度构建一个APK而不用担心它.但是,mipmap目录有时用于启动器图标的原因是因为构建脚本(aapt --preferred-configurations)剥离drawable- {density}目录而不是mipmap- {density}目录.这几乎似乎是在利用一个bug,但是你的引用来自Romain Guy和Diane Hackborn在https://plus.google.com/105051985738280261832/posts/QTA9McYan1L上的帖子显示它是设计的. (19认同)
  • 所以我删除mipmap的典型过程,将我的图标放在drawables中并构建一个APK是完美的.听起来mipmap对于我们大多数开发者来说都是不典型的,但它却被强加给了我们所有人. (3认同)
  • 所以你建议一个构建脚本,除了mipmap资源之外,除了mipmap资源之外的所有文件都会删除不正确的密度文件夹吗? (2认同)

Kaz*_*aki 77

似乎谷歌已经更新了他们的文档,因为所有这些答案,所以希望这将在未来帮助其他人:)在创建一个新的(新的)项目时,我自己也遇到过这个问题.

TL; DR:drawables可以作为dp特定资源优化的一部分被剥离.Mipmap不会被剥离.

不同设备上的不同主屏幕启动器应用程序以各种分辨率显示应用程序启动器图标.当应用资源优化技术移除未使用的屏幕密度的资源时,启动器图标可能会变得模糊,因为启动器应用程序必须升级较低分辨率的图标以供显示.为避免这些显示问题,应用程序应使用mipmap/资源文件夹作为启动器图标.无论密度剥离如何,Android系统都会保留这些资源,并确保启动器应用程序可以选择具有最佳分辨率的图标进行显示.

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

  • 这与导入图像资源时Android Studio的默认位置一致.启动器图标进入mipmap; 其他人进入绘画. (2认同)
  • 文档似乎又发生了变化,http://developer.android.com/tools/projects/index.html中似乎不存在mipmap(尽管Android文档的其他部分仍在尝试引用它)。 (2认同)

ser*_*nka 27

这些mipmap图像与其他熟悉的可绘制图像有何不同?

这是我试图解释差异的两分钱.在Android中处理图像时,有两种情况需要处理:

  1. 您希望为设备密度加载图像,并且您将"按原样"使用它,而不会更改其实际大小.在这种情况下,您应该使用drawables,Android将为您提供最佳的图像.

  2. 您希望为设备密度加载图像,但此图像将按比例放大或缩小.例如,当你想要显示更大的启动器图标,或者你有动画来增加图像的大小时,就需要这样做.在这种情况下,为了确保最佳图像质量,您应该将图像放入mipmap文件夹中.Android会做的是,它会尝试从更高密度的存储桶中获取图像,而不是将其扩展.这将增加图像的清晰度(质量).

因此,决定将图像放入何处的经验法则是:

  • 启动器图标始终进入mipmap文件夹.
  • 通常按比例放大(或缩小尺寸)且质量对应用程序至关重要的图像也会进入mipmap文件夹.
  • 所有其他图像是常用的绘图资源.


mat*_*ash 23

4.3中的mipmaps的Android实现正是1983年维基百科文章中解释的技术:)

mipmap集的每个位图图像是主纹理的缩小副本,但是在某个降低的细节水平上.虽然当视图足以以完整细节渲染时仍然会使用主纹理,但是当从远处或小尺寸查看纹理时,渲染器将切换到合适的mipmap图像(...).

虽然这被描述为用于3D图形的技术(因为它提到"从远处观看"),但它也适用于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);
}
Run Code Online (Sandbox Code Playgroud)

我不太清楚为什么这会特别适合应用程序图标.虽然平板电脑上的Android以及一些发射器(例如GEL)请求"一个密度更高"的图标来显示更大,但这应该使用常规机制(即drawable-xxxhdpi&c)来完成.

  • 事实上,这个答案是完全错误的.*only*的区别在于文件是否被剥离 - 它与是否使用mipmapping无关(在两种情况下都是如此).该文件夹有点名不副实; 他们可能应该称它为"drawable-nostrip"或其他东西. (2认同)
  • 很好的mipmaps解释,但[Kazuaki](http://stackoverflow.com/a/30365962/1536976)的答案引用谷歌文档条目似乎暗示它实际上不是原因. (2认同)

kre*_*ker 11

我在另一个线程中提到的一件值得指出的事情 - 如果你为不同的密度构建不同版本的应用程序,你应该知道"mipmap"资源目录.这与"可绘制"资源完全相同,只是在创建不同的apk目标时不参与密度剥离.

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