在安卓系统中,Bitmap和Drawable有什么区别?

87

我在谷歌上搜索了,但是没有找到任何一篇文章描述Android中Bitmap和Drawable之间的区别。


1
这个解决方案应该能够回答你的问题:solution - Jrom
4个回答

81

位图是一种位图图像的表现形式(类似于java.awt.Image)。Drawable是“可绘制对象”的抽象概念。它可以是一个位图(作为BitmapDrawable封装),但也可以是纯色、其他Drawable对象的集合或任何数量的其他结构。

大多数Android UI框架喜欢使用Drawable对象而不是Bitmap对象。View可以接受任何Drawable作为背景。ImageView可以显示前景Drawable。以资源形式存储的图像被加载为Drawable对象。


3
如果一个BitmapDrawable包装了一个位图,如果我们在其中调用位图的recycle()方法会发生什么?另外,对于API11及以上版本,recycle()方法有什么作用? - android developer
@androiddeveloper - 我不确定,但这不会是什么好事。一旦位图被BitmapDrawable包装,drawable就“拥有”该位图并应该管理其生命周期。如果您调用recycle(),则会干扰该关系。在最好的情况下,drawable将不会绘制任何内容;更有可能的是,稍后会抛出某种异常。根据文档,API11+中的recycle()与以往一样:它允许您在完成使用像素后立即释放本机像素。 - Ted Hopp
他们说这样可以释放位图的本地内存,但我们知道从API 11开始,与位图相关的一切(包括其原始数据)都在堆内存中,因此循环利用似乎是一件奇怪的事情... - android developer
@androiddeveloper - 看了一下源代码,似乎仍然存在一个原生位图。出于性能考虑,原始缓冲区被公开作为一个公共成员(虽然仍然从公共API中隐藏)。调用recycle()将释放原生位图;同时也会将成员缓冲区设置为null - Ted Hopp
是的,我也阅读了这篇文章,但是它并没有很有意义,因为他们在 Google IO 上说位图不再存储在本地内存中。我真的对这是如何实现感到困惑。 - android developer

46

位图不是一张图片。位图是一张位(注意名称:位图)的地图,它代表你可以在上面绘制东西的像素。它可能是你自己定制的位图(不是图片),例如正方形:

Bitmap bitmap = Bitmap.createBitmap(100, 100, Bitmap.Config.ARGB_8888);

或者您可以从图像创建位图对象:

Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.your_image);    

位图是像素的容器。而画布用于在您的位图上绘制一些东西(在位图像素上)。

关于Drawable的一切都在上面很好地描述了。

简而言之

有些人写道你在画布上绘制。你不是在画布上绘制。你使用Canvas帮助方法在位图像素上绘制。

Bitmap bitmap = Bitmap.createBitmap(100, 100, Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
canvas.drawColor(Color.RED) // now all bitmap pixels became red

好的回答值得+1 :) 感谢您通过代码行进行解释。 - HarshitMadhav
完美解释 - Tushar Srivastava

40

Drawable是可以绘制的东西。例如:布局、矢量图像(线、圆)、字体、图片等等。

位图(Bitmap)是特定类型的Drawable,它是一种图像,比如PNG、JPEG等。


12
Bitmapandroid.graphics.Bitmap)并不是Drawableandroid.graphics.drawable.Drawable)的子类。 - Ted Hopp
当然,这是我的错。我想说的是BitmapDrawable。 - Barmaley
但是文档中说:位图(Bitmap)是最简单的可绘制对象,是一张PNG或JPEG图片。 - mallaudin
1
我以为我从这个链接中复制了。https://developer.android.com/guide/topics/resources/drawable-resource#Bitmap - mallaudin

17

可绘制资源

Drawable 资源是一个通用概念,用于可以绘制到屏幕上的图形,您可以使用诸如 getDrawable(int) 等 API 检索它,或者使用属性(例如 android:drawableandroid:icon)应用于另一个 XML 资源。有几种不同类型的可绘制对象:

  • 位图文件,位于 .png、.jpg 或 .gif 格式的位图文件创建一个 BitmapDrawable

  • Nine-Patch 文件,带有可拉伸区域的 PNG 文件可以根据内容大小进行图像缩放(.9.png 格式),创建一个NinePatchDrawable

  • 图层列表,管理其他 Drawable 数组的 Drawable。这些按数组顺序绘制,因此最大索引的元素绘制在顶部,创建一个 LayerDrawable

  • 状态列表,引用不同的位图图形以供不同状态使用(例如,在按钮按下时使用不同的图像),创建一个 StateListDrawable 的 XML 文件。

  • 级别列表,定义一个可以管理多个备用 DrawableDrawable 的 XML 文件,每个都分配了最大数值,创建一个 LevelListDrawable

  • 转换可绘制对象,定义了一个可以在两个可绘制资源之间进行淡入淡出的 Drawable 的 XML 文件,创建一个 TransitionDrawable

  • 插入绘画,定义一个drawable使另一个drawable在指定距离内缩进。当一个View需要一个比视图实际边界更小的背景Drawable时,这非常有用。

  • 剪辑绘画,定义一个drawable基于此drawable当前级别值将其它drawable剪切,创建一个ClipDrawable

  • 缩放绘画,定义一个drawable基于当前级别值改变另一个drawable的大小,创建一个ScaleDrawable

  • 形状绘画,定义一个几何形状,包括颜色和渐变,创建一个ShapeDrawable

  • 还请参阅动画资源文档,了解如何创建AnimationDrawable

    注意:颜色资源也可以在XML中用作drawable。例如,在创建StateListDrawable时,可以为android: drawable属性引用颜色资源(android: drawable =“@ color / green”)。

    位图

    位图图像。Android支持三种格式的位图文件:.png(首选),.jpg(可接受),.gif(不鼓励使用)。

    您可以直接引用一个位图文件,使用文件名作为资源ID,或在XML中创建一个别名资源ID。

    注意:在构建过程中,aapt工具可以对位图文件进行无损图像压缩进行自动优化。例如,不需要超过256种颜色的真彩色PNG可能会转换为带有调色板的8位PNG。这将导致质量相同但内存占用更少的图像。因此,请注意在构建过程中该目录中放置的图像二进制文件可能会发生变化。如果您计划将图像作为位流读取以将其转换为位图,请将图像放入res/raw/文件夹中,那里它们将不会被优化。

    网页内容由stack overflow 提供, 点击上面的
    可以查看英文原文,
    原文链接