468

从 Android 4.3 (Jelly Bean) 开始,我们现在可以使用res/mipmap文件夹来存储“mipmap”图像。

例如,Android 版 Chrome将其图标存储在这些文件夹中,而不是更普通的res/drawable文件夹中。

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

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

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

参考:

Android 4.3 APIs文档有以下说法:

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

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

我没有看到任何可以帮助我理解的东西。


XML 位图资源有一个android:mipMap属性:

布尔值。启用或禁用 mipmap 提示。有关详细信息,请参阅 setHasMipMap()。默认值为假。

据我所知,这不适用于启动器图标。


这个问题是在 Google Groups 上提出的(资源名称“mipmap”的目的?!),Romain Guy 回答:

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

我觉得这几乎是有道理的,但不完全是。

我仍然倾向于使用 Randy Sugianto 的后续行动:

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


当然,Wikipedia 有一个“Mipmap”页面,它指的是 1983 年发明的一种较旧的技术,我与当前的 Android 实现不太相关。


这些天我们是否应该将所有应用程序图标存储在res/mipmap文件夹中,这些 mipmap 图像的指导方针是什么?


更新#1

这是一篇试图解释它的博客文章。

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

Chrome 的mipmap-hdpi文件夹包含三个图像。一个是 Chrome 标志,它自己。

Chrome mipmap-hdpi 图标.png

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

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


更新#2

2014 年 10 月 23 日的 Android 开发者博客文章再次确认了使用mipmap文件夹作为应用程序图标的想法:

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

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


更新#3

请注意,Android Studioic_launcher.png在文件夹中创建图标,mipmap...而不是在drawable...Eclipse 用来创建图标的文件夹中。


4

12 回答 12

266

mipmap 有两种不同的用途:

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

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

于 2014-06-05T17:25:04.077 回答
80

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

TL;DR:作为 dp 特定资源优化的一部分,drawable 可能会被剥离。Mipmap 不会被剥离。

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

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

于 2015-05-21T06:20:19.260 回答
29

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

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

  1. 您想为您的设备密度加载图像,并且将“按原样”使用它,而不更改其实际大小。在这种情况下,您应该使用可绘制对象,Android 将为您提供最合适的图像。

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

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

  • 启动器图标总是进入mipmap文件夹。
  • 经常放大(或极度缩小)并且质量对应用程序至关重要的图像也会进入mipmap文件夹。
  • 所有其他图像都是通常的drawables
于 2015-09-01T09:42:43.127 回答
24

4.3 中 mipmaps 的 Android 实现正是 1983 年在 Wikipedia 文章中解释的技术 :)

mipmap 集的每个位图图像都是主纹理的缩小副本,但细节程度有所降低。尽管当视图足以完整渲染它时仍会使用主纹理,但当从远处或以小尺寸查看纹理时,渲染器将切换到合适的 mipmap 图像 (...)。

尽管这被描述为一种用于 3D 图形的技术(因为它提到“从远处观看”),但它同样适用于 2D(翻译为“绘制的空间更小”,即“缩小”)。

对于一个具体的 Android 示例,假设您有一个带有特定背景可绘制对象的 View(特别是 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)来完成。

于 2014-06-08T01:59:13.243 回答
11

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

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

于 2015-01-17T01:34:15.653 回答
4

因为我一直在寻找一个明确的答案来确定通知图标的正确类型,所以我想在主题中添加这个明确的声明。它来自http://developer.android.com/tools/help/image-asset-studio.html#saving

注意:启动器图标文件位于与其他图标不同的位置。它们位于 mipmap/ 文件夹中。所有其他图标文件都位于项目的 drawable/ 文件夹中。

于 2016-03-22T00:38:38.910 回答
3

在 Android 中处理图像时,您需要处理两种情况:

  1. 您想要为您的设备密度加载图像,并且您将“按原样”使用它,而不更改其实际大小。在这种情况下,您应该使用可绘制对象,Android 将为您提供最合适的图像。
  2. 您想为您的设备密度加载图像,但该图像将被放大或缩小。例如,当您想显示一个更大的启动器图标,或者您有一个动画,这会增加图像的大小时,这是需要的。在这种情况下,为确保最佳图像质量,您应该将图像放入 mipmap 文件夹。Android 会做的是,它会尝试从更高密度的桶中获取图像,而不是按比例放大。

所以

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

  1. 启动器图标总是进入 mipmap 文件夹。

  2. 经常放大(或极度缩小)并且质量对应用程序至关重要的图像也会进入 mipmap 文件夹。

  3. 所有其他图像都是通常的可绘制对象。

来自这篇文章的引用。

于 2017-07-07T07:40:18.843 回答
2

在为不同密度构建单独的 apk 时,其他密度的可绘制文件夹会被剥离。这将使图标在使用更高密度启动器图标的设备中显得模糊。由于 mipmap 文件夹不会被剥离,因此最好使用它们来包含启动器图标。

于 2017-01-10T06:56:32.793 回答
2

当我们为不同密度构建单独的 APK 时,对于特定密度的 APK,其他密度的可绘制文件夹会被剥离。这将使图标在使用更高密度启动器图标的设备上显得模糊。由于 mipmap 文件夹不会被剥离,因此最好使用它们来包含启动器图标。

于 2021-10-18T06:40:44.593 回答
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/

于 2015-07-03T09:28:24.753 回答
1

如果您为 HDPI 等目标屏幕分辨率构建 APK,Android 资产打包工具 AAPT 可以剥离您不需要的其他分辨率的可绘制对象。但如果它在 mipmap 文件夹中,那么这些资产将保留在APK,无论目标分辨率如何。

于 2016-10-01T05:27:25.743 回答
-1

我对mipmap的理解或多或少是这样的:

当需要绘制图像时,鉴于我们有不同的屏幕尺寸和分辨率,必须进行一些缩放。

如果您的图像适合低端手机,当您将其缩放到 10 英寸平板电脑的大小时,您必须“发明”实际不存在的像素。这是通过一些插值算法完成的。必须发明的像素越多,过程花费的时间越长,质量开始失败。最好的质量是通过更复杂的算法获得的,需要更长的时间(例如,周围像素的平均值与复制最近的像素)。

为了减少必须发明的像素数量,您可以使用 mipmap 为同一图像提供不同的尺寸/分辨率,系统将选择最接近必须渲染的分辨率的图像并从那里进行缩放。这应该会减少发明像素的数量,从而节省用于计算这些像素以提供高质量图像的资源。

我在一篇文章中读到了这一点,该文章解释了缩放图像时 libgdx 中的性能问题:

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

于 2014-06-07T12:02:31.110 回答