自从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" />

引用:

Android 4.3 api文档有以下内容:

Using a mipmap as the source for your bitmap or drawable is a simple way to provide a quality image and various image scales, which can be particularly useful if you expect your image to be scaled during an animation. Android 4.2 (API level 17) added support for mipmaps in the Bitmap class—Android swaps the mip images in your Bitmap when you've supplied a mipmap source and have enabled setHasMipMap(). Now in Android 4.3, you can enable mipmaps for a BitmapDrawable object as well, by providing a mipmap asset and setting the android:mipMap attribute in a bitmap resource file or by calling hasMipMap().

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


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

布尔。启用或禁用mipmap提示。参见setHasMipMap() 更多的信息。默认值为false。

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


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

提供一个更大分辨率的图像是有用的 通常被计算(例如,在mdpi设备上,Launcher可能被计算) 想要更大的hdpi图标来显示大的应用程序快捷方式。)

我觉得这几乎说得通,但不完全是。

我仍然倾向于Randy Sugianto的后续观点:

这样做的好处是什么?有使用指南吗 Mipmaps,可能是为了更好的启动器图标?


当然,维基百科上有一个“Mipmap”的页面,这是一种1983年发明的老技术,我无法将其与当前的Android实现联系起来。


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


Update # 1

这里有一篇博客文章试图解释一下。

Android 4.3中用于绘图的Mipmapping

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

Chrome的mimmap -hdpi文件夹包含三张图片。一个是Chrome的logo。

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

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


更新# 2

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

为Nexus 6和Nexus 9准备好应用程序

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

最好的做法是把你的应用程序图标放在mipmap-文件夹(而不是 可绘制-文件夹),因为它们用于不同的分辨率 器件的电流密度。例如,xxxhdpi应用程序图标可以是 用于xxhdpi设备的启动器上。


更新# 3

注意,Android Studio在mipmap中创建了ic_launcher.png图标…文件夹而不是可绘制的…Eclipse用来在其中创建它们的文件夹。



当前回答

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

mipmap集的每个位图图像都是 主要纹理,但在一定程度上减少了细节。虽然 当视图足够渲染时,主纹理仍将被使用 它的细节充分,渲染器将切换到合适的mipmap图像 (…)当从远处或小尺寸观察纹理时。

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

对于一个具体的Android例子,假设你有一个带有特定背景可绘制对象的视图(特别是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)要求图标“更高密度”以显示它更大,但这应该使用常规机制(即draw -xxxhdpi, &c)来完成。

其他回答

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

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

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

注意:启动程序图标文件驻留在不同的位置 其他图标。它们位于mipmap/文件夹中。所有其他图标 文件驻留在项目的可绘制/文件夹中。

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

mipmap集的每个位图图像都是 主要纹理,但在一定程度上减少了细节。虽然 当视图足够渲染时,主纹理仍将被使用 它的细节充分,渲染器将切换到合适的mipmap图像 (…)当从远处或小尺寸观察纹理时。

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

对于一个具体的Android例子,假设你有一个带有特定背景可绘制对象的视图(特别是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)要求图标“更高密度”以显示它更大,但这应该使用常规机制(即draw -xxxhdpi, &c)来完成。

我对mipmap的理解大致是这样的:

当需要绘制图像时,考虑到我们有不同尺寸的屏幕分辨率,一些缩放将不得不参与。

如果你有一个适合低端手机的图像,当你把它放大到10英寸平板电脑的大小时,你必须“发明”一些实际上不存在的像素。这是通过一些插值算法来实现的。需要创造的像素越多,制作过程所需的时间就越长,质量就会开始下降。最好的质量是通过更复杂的算法获得的,这需要更长的时间(例如,平均周围的像素vs复制最近的像素)。

为了减少必须创建的像素数量,可以使用mipmap为同一图像提供不同大小/分辨率的解决方案,系统将选择与必须渲染的分辨率最近的图像,并从那里进行缩放。这将减少发明像素的数量,节省用于计算这些像素以提供高质量图像的资源。

我在一篇解释libgdx缩放图像时的性能问题的文章中读到过:

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

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

以下是我的观点,试图解释其中的区别。在Android中处理图像时有两种情况:

You want to load an image for your device density and you are going to use it "as is", without changing its actual size. In this case you should work with drawables and Android will give you the best fitting image. You want to load an image for your device density, but this image is going to be scaled up or down. For instance this is needed when you want to show a bigger launcher icon, or you have an animation, which increases image's size. In such cases, to ensure best image quality, you should put your image into mipmap folder. What Android will do is, it will try to pick up the image from a higher density bucket instead of scaling it up. This will increase sharpness (quality) of the image.

因此,决定把你的图像放在哪里的经验法则是:

启动器图标总是进入mipmap文件夹。 图片,通常是按比例放大(或极度缩小),其质量是至关重要的应用程序,也进入mipmap文件夹。 所有其他图像通常都是可绘制的。