本人才疏学浅,翻译的不对的地方请指出,而且本人不是针对原文一字一句翻译的,适当作些调整,翻译大概意思,并添加一些小批注。
这些文章提供了一个可行的解决办法,适合初学者应用,它介绍了各种处理图片的方式,可以应用在程序中,未必是完美的。
Displaying Bitmaps Efficiently这是文档中的新的一部分:大概翻译下内容:
这章覆盖了一些常用的技术,是关于处理Bitmap对象的,可以帮助您的UI快速响应,避免内存溢出。如果您不小心,可能很快地消耗了内存,导致程序的崩溃。抛出异常:java.lang.OutofMemoryError: bitmap size exceeds VM budget.
关于为什么在Android应用在加载Bitmap时有限制,主要有以下几点:
移动设备只有有限的系统资源,Android设备只有16mb可用于一个程序。android compatibility definition document(CDD)[url]http://source.android.com/compatibility/downloads.html [/url],第三节Virtual Machine Compatility 给出了不同屏幕和分辨率的最小应用内存需求说明,应用程序需要在这样的内存限制中优化。
Bitmap会消耗很多的内存,尤其像照片,摄像头在GalaxyNexus拍一张照片有2592*1936像素,如果bitmap使用ARGB_8888配置(2.3默认的),加载这张照片到内存需要消耗约19mb内存,(2592*1936*4bytes)。就超过了应用的内存限制了。
android的ui经常需要加载几张bitmap位图,像ListView,GridView,ViewPager这样的组件在屏幕上通常会有多张的位图。
Loading Large Bitmaps Efficiently
图片有各种大小,开状,多数情况下对于特定的android程序ui来说它们是偏大的。如Gallery应用显示照片跟摄像头的比就小得多了。
在内存受限的情况下,你只需要加载一些低分辨率的图片,一张大分辨率的图片并没有提高视觉效果,还占用更多的内存,
这节告诉您如何解码大的图片,而不超过系统的限制。
Read Bitmap Dimensions and Type
BitmapFactory类提供了一些解码的方法decodeByteArray(),decodeFile(),decodeResource()等,来创建一个位图资源。需要选择正确的方法来解析图片资源。这些方法会构造一个位图,然后申请内存,容易造成oome,每一个方法都有一个额外的信息为您 分配解码选项BitmapFactory.Options类,设置inJustDecodeBounds属性为true时,解码避免了内存占用,它不会返回位图信息,而设置了outWidth,outHeight,outMimeTYpe。这些就可以供读取解析度与类型了。
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeResource(getResources(), R.id.myimage, options);
int imageHeight = options.outHeight;
int imageWidth = options.outWidth;
String imageType = options.outMimeType;
避免oome的出现可以先判断dimensions,再解码
Load a Scaled Down Version into Memory
加载一个缩放后的版本到内存中,位图的dimensions从上面得到后,可用于决定是否位图可以加载到内存,或加载一个缩放后的版本。
这里给出一些因素供参考:
估计内存的消耗。
计算应用的其它部分占用的内存与当前图片应该占用的内存。
贴图目标需要多大的dimensions,如ImageView,或其它ui。
屏幕的大小与解析度。
如,显示在128x96像素的ImageView中不值得加载一个1024*768像素的图片。
在BitmapFactory.Options 设置inSampleSize的值就可以改变了。
如2048*1536像素的图片解码时inSampleSize=4,就会得到一个512*384大小的位图了,使用0.75mb内存,而不是12mb。
下面提供一个方法来计算 :
public static int calculateInSampleSize(
BitmapFactory.Options options, int reqWidth, int reqHeight) {
// Raw height and width of image
final int height = options.outHeight;
final int width = options.outWidth;
int inSampleSize = 1;
if (height > reqHeight || width > reqWidth) {
if (width > height) {
inSampleSize = Math.round((float)height / (float)reqHeight);
} else {
inSampleSize = Math.round((float)width / (float)reqWidth);
}
}
return inSampleSize;
}
注意:使用2的倍数会对解码更高效的(我估计是二进制的原因),
使用这个方法,首先需要options.inJustDecodeBounds = true;先解码一次,然后再使用新的inSampleSize值,options.inJustDecodeBounds = false来解码需要的图片。
public static Bitmap decodeSampledBitmapFromResource(Resources res, int resId,
int reqWidth, int reqHeight) {
// First decode with inJustDecodeBounds=true to check dimensions
final BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeResource(res, resId, options);
// Calculate inSampleSize
options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);
// Decode bitmap with inSampleSize set
options.inJustDecodeBounds = false;
return BitmapFactory.decodeResource(res, resId, options);
}
这就提供了简易的加载图片的方法了:
mImageView.setImageBitmap(
decodeSampledBitmapFromResource(getResources(), R.id.myimage, 100, 100));
剩下两篇下面继续
分享到:
相关推荐
"Displaying Bitmaps Efficiently"这一主题是Android 6.0官方开发平台上的重要内容,旨在帮助开发者避免内存溢出、提高应用响应速度以及优化用户体验。 1. **Loading Large Bitmaps Efficiently** - **Read ...
Android 开发者网站上 Training 部分,Building Apps with Graphics & Animation -> Displaying Bitmaps Efficiently部分的实例 demo
"DisplayingBitmaps"这个主题主要关注如何有效地缓存和管理Bitmap以避免这样的问题。Google官方提供了一些最佳实践,包括使用LruCache和DiskCache来优化内存使用。 **LruCache** LruCache(Least Recently Used ...
"android-DisplayingBitmaps"项目是专门为解决这些问题而设计的一个示例库,它已被迁移到一个新的仓库,意味着它可能包含了最新的优化技术和最佳实践。这个库主要关注如何高效地在Android应用中加载、解码和显示位图...
Android 媒体数据库示例(原始 DisplayingBitmaps 示例 ( ))当前版本 1.0 Beta 示例演示如何从主 UI 线程有效地从 Android sd 卡(图库)加载大型位图、缓存位图(在内存和磁盘中)、管理位图内存并在 UI 元素 - ...
这个示例项目名为"DisplayingBitmaps",包含了各种实用技巧和最佳实践。 首先,我们要理解Android系统对内存管理的敏感性,特别是在低内存设备上。Android的Bitmap类用于表示图像,但如果不妥善处理,可能导致内存...
在Android开发中,内存管理是优化应用性能的关键...通过对DisplayingBitmaps示例的学习,开发者可以更好地理解和掌握RecyclingImageView的工作机制,从而在自己的应用中有效地管理图片资源,提高应用的性能和用户体验。
A_centralized_system_for_displaying_and_stylizing__聚焦聚焦_A_centralized_system_for_displaying_and_stylizing__focus-rings.zip_A_centralized_system_for_displaying_and_stylizing__focus-rings
Check out this article for displaying large bitmaps into the desired area of your dialog box in its original size with a scrolling technique used to show the entire bitmap. 滚动显示位图 在VC++环境下...
本项目"MFC-Project-Gif-displaying"的目标是通过MFC源码来实践显示Gif图像的功能。 首先,我们来看关键的源文件: 1. **PictureEx.cpp**:这个文件可能包含了处理图像显示的核心功能,尤其是针对Gif格式的解析和...
### 计算与显示疲劳结果 #### 引言 疲劳分析是材料工程中一个非常重要的领域,它关注的是材料在循环载荷作用下发生破坏的可能性。ANSYS疲劳模块提供了广泛的功能来执行计算并呈现分析结果。本文将详细介绍该模块...
这个“Simple java library for displaying dates as relative time .zip”文件提供了一个简洁的解决方案,帮助开发者轻松实现这一功能。下面我们将详细讨论这个库的工作原理、使用方法以及它可能涉及的Java日期和...
A slider widget with a popup bubble displaying the precise value selected..zip,A slider widget with a popup bubble displaying the precise value selected. Android library made by @Ramotion - ...
### 显示PC上的数据:TinyOS中的传感器网络与PC集成 #### 一、引言 在本章节中,我们将探讨如何将传感器网络与个人电脑(PC)进行集成,以实现传感器读数在PC上的显示,并且能够从PC向传感器节点(motes)发送数据...
在C#编程中,创建一个应用程序来显示不同的三角形图案是一项常见的练习,它有助于理解循环结构,特别是for循环的工作原理。在这个案例中,我们需要创建一个程序来分别展示四种不同的三角形模式,每一种图案都在下一...
"Chat User Control with WebBrowser Control as Displaying Engine" 是一个技术主题,主要探讨如何利用Windows Forms中的WebBrowser控件作为聊天用户界面的显示引擎。这个标题暗示了一个自定义的用户控件(User ...
标题中的"A website for updating and displaying the CBDL tag game data"表明我们要讨论的是一个专门为更新和展示CBDL(可能是一个特定游戏或联赛的缩写)标签游戏数据而设计的网站。这个网站可能是为了实时追踪...