一说到Bitmap,所以人都会想到回收,内存溢出等问题,我一直对Bitmap存在的实例化方法不太懂,现在就来看看。
大家都知道有个BitmapFactory类,该类有好多静态方法可以实例化一个Bitmap,看下源码知道, BitmapFactory对Bitmap的实例化最终都归到native层的方法来,我们看下所有的native方法
private static native Bitmap nativeDecodeStream(InputStream is,byte[] storage, Rect padding, Options opts); private static native Bitmap nativeDecodeStream(InputStream is, byte[] storage, Rect padding, Options opts, boolean applyScale, float scale); private static native Bitmap nativeDecodeFileDescriptor(FileDescriptor fd,Rect padding, Options opts); private static native Bitmap nativeDecodeAsset(int asset, Rect padding, Options opts); private static native Bitmap nativeDecodeAsset(int asset, Rect padding, Options opts,boolean applyScale, float scale); private static native Bitmap nativeDecodeByteArray(byte[] data, int offset, int length, Options opts); private static native byte[] nativeScaleNinePatch(byte[] chunk, float scale, Rect pad); private static native boolean nativeIsSeekable(FileDescriptor fd);
可以看到主要有这几类
1::nativeDecodeStream , 2:nativeDecodeFileDescriptor,3:nativeDecodeAsset,4:nativeDecodeByteArray 方法可以解析出Bitmap对象
看下各个方法的源码,发现
1:decodeFile,decodeResourceStream,decodeResource这三种得到Bitmap对象的方法最终都会调用方法decodeStream来得到Bitmap对象,而decodeStream会根据图片源的不同,分别调用nativeDecodeStream或者nativeDecodeAsset方法来得到Bitmap对象。
2:decodeByteArray方法会调用nativeDecodeByteArray方法来得到Bitmap对象。
3:decodeFileDescriptor方法会调用nativeDecodeFileDescriptor方法来得到Bitmap对象。
还有一种方法可以实例化一个Bitmap对象,那就是Bitmap.createBitmap(),看下源码:最终会调用
private static Bitmap createBitmap(DisplayMetrics display, int width, int height, Config config, boolean hasAlpha) { if (width <= 0 || height <= 0) { throw new IllegalArgumentException("width and height must be > 0"); } Bitmap bm = nativeCreate(null, 0, width, width, height, config.nativeInt, true); if (display != null) { bm.mDensity = display.densityDpi; } if (config == Config.ARGB_8888 && !hasAlpha) { nativeErase(bm.mNativeBitmap, 0xff000000); nativeSetHasAlpha(bm.mNativeBitmap, hasAlpha); } else { // No need to initialize it to zeroes; it is backed by a VM byte array // which is by definition preinitialized to all zeroes. // //nativeErase(bm.mNativeBitmap, 0); } return bm; }
最后还是调用native层的代码nativeCreate来创建一个Bitmap对象。
那么Bitmap对象被创建出来后,保存在哪里呢?这个问题,以后再研究。
现在我想做个实验,
实验1:对于一个ImageView显示图片,用xml中的src属性和background属性占用的内存有区别么,
经实验,发现Heap里面的Allocated分配内存一样大,答案:没区别。
实验2:用xml中的scr属性和用BitmapFactory解析出Bitmap然后在setImageBitmap到ImgeView中
占用的内存有区别么?经实验,发现Heap里面的Allocated分配内存一样大,答案:没区别。
实验3:给ImageView设置一张小图,然后铺满屏,和给ImageView设置一张大图,铺满屏,
占用内存有区别么?经实验,发现设置大图的情况下,Heap里面的Allocated分配的内存
比小图的时候要大的多,答案:设置大图的情况占用内存比设置小图的情况大多了。
实验4:给ImageView设置一张小图,一种铺满屏,一种保持本身大小,占用内存有却别么?
经实验,占用内存一样大。
实验5:同一张图片,jpg格式与png格式占用的内存是否相同?同一张图片的意思是只是用PS改了
下后缀名,jpg图片大小:512K, png图片大小:810K。经实验两张图片占用内存一模一样大。
结论:图片占用内存的大小跟图片显示出来的大小没有关系。一张图片不管你是放大还是缩小,它所占用的内存还是一样大,除非采用采样压缩图片的大小才会影响到图片对内存占用的大小。
相关推荐
var bimap = new BiMap bimap . push ( "key" , "value" ) ; bimap . key ( "key" ) ; // => "value" bimap . val ( "value" ) ; // => "key" bimap . push ( "France" , [ "Paris" , "Lyon" , "Marseille" ] ) ; ...
用法安装要在您的Rust项目中使用bimap-rs,请将以下内容添加到Cargo.toml的依赖项部分:bimap =“ 0.4” serde兼容性bimap-rs可选地支持通过serde对BiHashMap和BiBTreeMap进行序列化和反序列化。 为避免不必要的依赖...
以下是一些关于Bitmap、byte[]、Drawable相互转化的实例: 1. **Bitmap转byte[]**:Bitmap对象可以通过`compress()`方法压缩成字节数组,通常会选择特定的格式如PNG或JPEG,并设置压缩质量。例如,`bm.compress...
- **创建与初始化**:Elixir-Bimap库提供了`Bimap.new/0`和`Bimap.new/2`函数来创建空的Bimap或指定初始键值对的Bimap。 - **添加与删除**:你可以使用`Bimap.put/3`添加新的键值对,`Bimap.remove/2`来移除键值对...
Rust是一种系统级编程语言,强调安全、并发和速度,而`bimap-rs`是一个专门为Rust设计的双射图(Bi-directional Map)库。本文将深入探讨`bimap-rs`库以及双射图在Rust编程中的应用。 双射图,也称为双向映射,是一...
主要内容包括三部分:第一部分从数据的产生、采集、计算、存储、消费端到端的角度介绍大数据技术的起源、发展、关键技术点和未来趋势,结合生动的业界最新产品,以及学术界最新的研究方向和成果,让深奥的技术浅显...
在谷歌Collection包中,特别是其Guava子库,包含了丰富的数据结构,如Multiset、Multimap、BiMap等,以及各种实用的集合操作工具类。 首先,我们要关注的是`BiMap`,这是一个双向映射的接口,它要求键和值之间的...
首先,创建一个名为`Map_ValueGetKey`的类,并实例化一个HashMap对象`map`。然后定义一个`getKey`方法,该方法接受一个值作为参数,其目的是找到与该值相匹配的所有键。 方法的核心在于调用`entrySet()`方法,它...
`MapMaker` 提供了一个高度定制化的 Map 构建器,可以用来创建高性能的缓存 Map。它支持并发访问、弱引用键/值、自定义加载因子等功能。 - **创建示例**: ```java LoadingCache, String> cache = CacheBuilder....
1. 首先,我们需要一个`ReadBitmap`类,包含三个方法:`readByte`、`Bytes2Bimap`和`saveMyBitmap`。 - `readByte`方法是整个流程的核心,它接收一个`Context`对象、图片文件名(例如“image.jpg”)和一个整型数组...
对于集合来说,这就意味着一旦集合被初始化后,你就不能向其添加、删除或更改任何元素。这样的集合在多线程环境下特别有用,因为它们是线程安全的。 描述部分进一步阐述了不可变集合的概念。它们的数据项是在创建时...
读256色bimap格式文件,具有放大,缩小,平移,旋转等功能
bimap = BiMap {Int,String} () bimap . left[ 1 ] = " one " bimap . left[ 2 ] = " two " bimap . right[ " three " ] = 3 @assert bimap . left[ 1 ] == " one " @assert bimap . right[ " two " ] == 2 @assert ...
以下是一些关于Android Drawable和Bitmap转换的实例详解: 1. **Bitmap转Drawable** 当我们有一个Bitmap对象,需要将其设置为ImageView或者其它可显示图像的组件时,通常会将其转换为Drawable。这个过程相对简单,...
4. **BiMap**:BiMap 是双向映射,不仅保证键的唯一性,还保证值的唯一性,提供了更严格的键值对管理。 5. **MapMaker**:这是一个用于构建自定义 Map 实例的工具,可以设置缓存策略、并发级别等高级特性。 6. **...
例如,你可以使用`bimap`来同时转换一个列表的键和值,使用`bifoldMap`对树结构进行聚合,或者使用`bitraverse`在解析或序列化过程中同时处理两个数据类型。 总的来说,深入理解Haskell中的`bifunctors`、`...
4. **序列化**:`boost::serialization`库可以帮助序列化和反序列化对象,方便数据存储和传输。 在"Boost Demo"这个项目中,开发者可能会展示如何在Android应用中引入Boost库,如何通过JNI调用C++代码,以及如何在...
`bimap`是Boost库的一部分,全称是Bi-directional Map,双向映射,它提供了一种数据结构,允许在两个集合之间进行双向映射。虽然在Qt的TabWidget示例中通常不会直接用到Boost库,但在某些复杂的Qt应用中,可能会结合...
5. **BiMap**: `BiMap` 是双向映射的 Map,它确保了每个键都对应唯一的值,同时每个值也对应唯一的键。这意味着,当你通过键获取值时,可以通过值反向获取键,这是标准 `Map` 所不具备的特性。 6. **Table**: `...
3. **容器与数据结构**(Containers and Data Structures):如`multi_array`(多维数组)、`flat_map`(扁平化的映射)和`bimap`(双向映射),这些容器提供了更灵活的选择来存储和组织数据。 4. **泛型编程**...